Compare commits
123 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e0cd298011 | |||
| a504dc2b03 | |||
| 7d2008772e | |||
| 843103429b | |||
| 77e2f4d874 | |||
| cc1ed9a178 | |||
| 478d23acc9 | |||
| 7d2a442309 | |||
| 57bccd9fe6 | |||
| 224d867d4a | |||
| 37919982cd | |||
| 019021af06 | |||
| 2c3c294362 | |||
| 7ce552e074 | |||
| 4e1e0c9d31 | |||
| 7c0b8b6389 | |||
| 95488f9772 | |||
| 4142e9221a | |||
| e4ceb44f8c | |||
| 24b1c96cab | |||
| db4e15b507 | |||
| 5dbaa1df7c | |||
| 84f5602e3f | |||
| 557a30d959 | |||
| 6cb705ffcb | |||
| f21c0933b0 | |||
| ffb0815238 | |||
| f613f010af | |||
| 3ab120aa0e | |||
| c29fbda989 | |||
| 45170dd1e6 | |||
| 4cf68072e1 | |||
| 8dfe713afb | |||
| 1b66c3c4cd | |||
| 527e138b83 | |||
| 2ac7731c52 | |||
| 6b875fbd16 | |||
| 1e04b08ff4 | |||
| 594c7a0301 | |||
| 03a17e9f29 | |||
| 54ad72c477 | |||
| 131fa6e6d3 | |||
| 7ab01f9580 | |||
| 89697d0528 | |||
| a5a19cae62 | |||
| ec608a8909 | |||
| df6436b512 | |||
| fcdffd247c | |||
| 9bf20be350 | |||
| 0b942360b7 | |||
| 07cfe5a73e | |||
| 96c2e34a04 | |||
| e22d097b92 | |||
| e11ca3476d | |||
| d6e19a59b1 | |||
| 1fa6beedb9 | |||
| 01aef1b3ae | |||
| 7da464ea0c | |||
| ff0842906f | |||
| 57defd5686 | |||
| f5a9d9a06a | |||
| 0c0d677a82 | |||
| 7f58c31d6b | |||
| 44cf2f131e | |||
| 1bcab31ad7 | |||
| ae90ebed3a | |||
| 3b61787a62 | |||
| 3ace94df91 | |||
| fa2eec96f9 | |||
| 48d6931c68 | |||
| 7e8664c577 | |||
| 3c16ff0ca2 | |||
| 2ecaf7f242 | |||
| dd6de15d8c | |||
| 13669ecef3 | |||
| 23852b00c3 | |||
| 9b120daae0 | |||
| a60fe1fa4a | |||
| eda8130671 | |||
| 09ca346abe | |||
| 9ac0473138 | |||
| ba14f6cfdb | |||
| e2646ee70e | |||
| 9b68152bd0 | |||
| 0f12a7e2bb | |||
| c998469b3a | |||
| 37722738aa | |||
| 3f1d83e2e7 | |||
| 1723e9dc8d | |||
| 02adb54f61 | |||
| 820da91c77 | |||
| c083d042c1 | |||
| fd72713d98 | |||
| 7dcb9f58f1 | |||
| 0c4d809316 | |||
| 850177b60c | |||
| 048a53644e | |||
| 3b1c61bae2 | |||
| a4a389e5c3 | |||
| 542512c0c5 | |||
| ebd4788e13 | |||
| 9cf842980a | |||
| b7eff051da | |||
| 372f090c80 | |||
| 6d68a423c3 | |||
| 987559f370 | |||
| d4a09445c7 | |||
| 56d8123f44 | |||
| f10dd3f950 | |||
| ce0cb481bc | |||
| 491a0cf26e | |||
| 1ba8c79a11 | |||
| 88a0307c4a | |||
| 5d9c2fa33b | |||
| 10affbc629 | |||
| bc5c8c4950 | |||
| 2f5db4a667 | |||
| fa0251f5b2 | |||
| fad5f5b7f3 | |||
| e8996427bd | |||
| c40c9ea517 | |||
| 227bed27b8 | |||
| 8e634d5739 |
@@ -12,7 +12,7 @@ Multi-service monorepo for the Darano financial/crypto platform. Each subdirecto
|
|||||||
| `auth/` | Go (gRPC) | Authorization — OTP, JWT, permissions, identity |
|
| `auth/` | Go (gRPC) | Authorization — OTP, JWT, permissions, identity |
|
||||||
| `wallet/` | Go (gRPC) | Wallet — assets, transactions, Stellar blockchain, market |
|
| `wallet/` | Go (gRPC) | Wallet — assets, transactions, Stellar blockchain, market |
|
||||||
| `ui/` | TypeScript/Next.js | Customer-facing frontend |
|
| `ui/` | TypeScript/Next.js | Customer-facing frontend |
|
||||||
| `AdminPanel/` | Python/Django | Internal admin panel (bypasses api, hits Postgres directly) |
|
| `AdminPanel/` | Python/Django | Internal admin: direct SQL reads, authenticated service-owned writes |
|
||||||
| `proto/` | Protobuf | Central schema definitions shared by all services |
|
| `proto/` | Protobuf | Central schema definitions shared by all services |
|
||||||
| `DevOps/` | Docker Compose | Infrastructure — Postgres, Redis, RabbitMQ, MinIO, Traefik |
|
| `DevOps/` | Docker Compose | Infrastructure — Postgres, Redis, RabbitMQ, MinIO, Traefik |
|
||||||
| `docs/` | MkDocs | Documentation site |
|
| `docs/` | MkDocs | Documentation site |
|
||||||
@@ -23,17 +23,18 @@ Multi-service monorepo for the Darano financial/crypto platform. Each subdirecto
|
|||||||
|
|
||||||
```
|
```
|
||||||
Browser/Client → api (REST/HTTP) → auth, wallet/market/alert (gRPC)
|
Browser/Client → api (REST/HTTP) → auth, wallet/market/alert (gRPC)
|
||||||
AdminPanel ──────────────────────→ Postgres directly (bypasses api)
|
AdminPanel ──reads───────────────→ Postgres
|
||||||
|
AdminPanel ──authenticated gRPC──→ wallet (asset administration)
|
||||||
```
|
```
|
||||||
|
|
||||||
The `api` gateway is the **only** HTTP-facing service. All inter-service communication is gRPC.
|
The `api` gateway is the **only** HTTP-facing service. All inter-service communication is gRPC.
|
||||||
|
|
||||||
### API Gateway (api/)
|
### API Gateway (api/)
|
||||||
|
|
||||||
- **Entry**: `api/main.go` → `cmd.Execute()` (Cobra) → `cmd/serve.go` sets up Gin router
|
- **Entry/composition**: `api/main.go` → `cmd.Execute()` (Cobra) → `cmd/apiRuntime`, which explicitly owns clients, handlers, router, HTTP servers, permission synchronization, and cleanup.
|
||||||
- **Service layer**: `api/service/main.go` — `DaranoService` interface composes all upstream gRPC clients. Each service gets a persistent gRPC connection created lazily, with automatic reconnection after a **2-minute timeout**. URL lookup uses **reflection** on the `Peer` struct via `ServicesEnum` — field names must match `ServicesEnum` values exactly.
|
- **Upstream boundary**: `api/application/port.Upstreams` composes generated service contracts. `api/infrastructure/grpcclient` implements lazy connection creation, active-call tracking, configurable idle closure (**2-minute default**), reconnection, health checks, and explicit shutdown without reflection.
|
||||||
- **Handlers**: `api/handler/` — one file per domain. All handlers embed `service.DaranoService`.
|
- **Handlers**: `api/interface/http/handler/` — one file per domain. Handlers depend on `application/port.Upstreams`.
|
||||||
- **Routing**: `api/handler/routing.go` — routes grouped into `/v1/public/`, `/v1/client/`, `/v1/admin/`. The `/v1/internal/` routes are commented out (placeholder).
|
- **Routing**: `api/interface/http/handler/routing.go` — routes grouped into `/v1/public/`, `/v1/client/`, `/v1/admin/`. The admin group is protected but currently empty; internal routes remain disabled.
|
||||||
- **Middleware chain** (order matters): APM → Profiling → Prometheus → CORS → JSON → I18n → Error → optional Logger
|
- **Middleware chain** (order matters): APM → Profiling → Prometheus → CORS → JSON → I18n → Error → optional Logger
|
||||||
- **Endpoints**: `GET /` (health), `GET /metrics` (Prometheus), `GET /swagger/*any`, `GET /ws` (WebSocket)
|
- **Endpoints**: `GET /` (health), `GET /metrics` (Prometheus), `GET /swagger/*any`, `GET /ws` (WebSocket)
|
||||||
- **Profiling**: `net/http/pprof` is imported (blank import `_`); runs on a separate port when `Profiling.Enabled` in config
|
- **Profiling**: `net/http/pprof` is imported (blank import `_`); runs on a separate port when `Profiling.Enabled` in config
|
||||||
@@ -47,7 +48,7 @@ Single binary hosts multiple sub-services via Cobra subcommands: `wallet`, `mark
|
|||||||
### Config
|
### Config
|
||||||
|
|
||||||
- **Go services** use `knadh/koanf` (not `fig` as older docs may suggest) to parse TOML config files
|
- **Go services** use `knadh/koanf` (not `fig` as older docs may suggest) to parse TOML config files
|
||||||
- **Global singleton**: `config.Cfg` — a `sync.Once` ensures it's initialized exactly once
|
- **Explicit ownership**: commands load configuration once and inject it through composition; legacy `config.Cfg` globals were removed
|
||||||
- **Defaults baked into code**: `config.go` in `api/` sets default `ipg_callback_url` and `ui_server_error_status_url` before loading the TOML file (TOML overrides defaults)
|
- **Defaults baked into code**: `config.go` in `api/` sets default `ipg_callback_url` and `ui_server_error_status_url` before loading the TOML file (TOML overrides defaults)
|
||||||
- **Struct tags**: use `koanf:"field-name"` (not env vars)
|
- **Struct tags**: use `koanf:"field-name"` (not env vars)
|
||||||
|
|
||||||
@@ -132,30 +133,31 @@ Proto definitions live in `proto/` with subdirectories: `base/`, `auth/`, `walle
|
|||||||
|
|
||||||
## Go Service Layer Pattern
|
## Go Service Layer Pattern
|
||||||
|
|
||||||
Both `auth` and `wallet` follow a layered architecture:
|
The active Go services follow inward-facing layers:
|
||||||
|
|
||||||
- **`config/`** — TOML config via koanf. `config.Cfg` global singleton, `sync.Once` initialized.
|
- **`domain/`** — entities, exact value objects, errors, and ports without transport/framework ownership.
|
||||||
|
- **`application/`** — business policies and orchestration against domain ports.
|
||||||
|
- **`infrastructure/`** — koanf configuration, PostgreSQL/Redis, external clients, queues, Stellar, and generated-client adapters.
|
||||||
|
- **`interface/`** — gRPC/HTTP/process adapters and protocol mapping.
|
||||||
- **`domain/stub/go/`** — Generated protobuf Go code. **Never edit manually.**
|
- **`domain/stub/go/`** — Generated protobuf Go code. **Never edit manually.**
|
||||||
- **`cmd/`** — Cobra CLI entry points. Subcommands map to serve modes.
|
- **`cmd/`** — Cobra CLI entry points. Subcommands map to serve modes.
|
||||||
- **`repository/`** — Data access. Aggregates `IPostgres`, `IRedis`, `IService`, and `IQueue` (wallet only) interfaces.
|
- **`repository/` / `usecase/`** — remaining compatibility composition/interfaces; implementations live in infrastructure and new business logic belongs in application/domain.
|
||||||
- **`core/`** (wallet) / **`usecase/`** (auth) — Business logic. Implements gRPC server interfaces from proto.
|
|
||||||
- **`util/`** — Shared helpers; no business logic.
|
|
||||||
|
|
||||||
In `auth`, `usecase.UseCase` interface directly embeds the generated gRPC server interfaces (`authv1.AuthorizationServiceServer`, `authv1.InternalAuthorizationServiceServer`).
|
In `auth`, `usecase.UseCase` interface directly embeds the generated gRPC server interfaces (`authv1.AuthorizationServiceServer`, `authv1.InternalAuthorizationServiceServer`).
|
||||||
|
|
||||||
In `wallet`, `core/` contains sub-packages: `walletImp/`, `marketImp/`, `alertImp/`, `cronJobs/`.
|
In `wallet`, runtime adapters live under `interface/grpc` and `interface/process`; the superseded `core/*Imp` packages no longer exist.
|
||||||
|
|
||||||
## API Gateway Patterns
|
## API Gateway Patterns
|
||||||
|
|
||||||
### Request/Response Flow
|
### Request/Response Flow
|
||||||
|
|
||||||
```
|
```
|
||||||
HTTP request → middleware chain → routing.go → handler/*.go → DaranoService.gRPC → backend service
|
HTTP request → interface/http middleware → interface/http/handler → application Upstreams port → infrastructure/grpcclient → backend service
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Response helpers**: `handler/response.go` — `JSON()` and `JSONList[X]()` wrap responses in `transport.Response{Meta, Data}`. `JSONList` has a known issue: pointer-to-empty-slice marshals as `null` instead of `[]`, fixed via `EmptyList{make([]string, 0)}` sentinel.
|
- **Response helpers**: `interface/http/handler/response.go` — `JSON()` and `JSONList[X]()` wrap responses in `transport.Response{Meta, Data}`. Pointer-backed empty lists use the `EmptyList` sentinel to serialize `[]` rather than `null`.
|
||||||
- **HTTP-to-gRPC context**: `handler/contextWithMetadata()` converts HTTP headers to gRPC metadata using `util.ConvertHTTPHeaderToGRPCMetadata()`.
|
- **HTTP-to-gRPC context**: `interface/http/handler/contextWithMetadata()` copies HTTP headers into incoming and outgoing gRPC metadata.
|
||||||
- **Handler interface**: Each handler file defines a `handle` interface; `handler/main.go` defines `Server` struct embedding `service.DaranoService`.
|
- **Handler interface**: `interface/http/handler.Server` receives the `application/port.Upstreams` boundary and configuration explicitly.
|
||||||
|
|
||||||
### Route conventions
|
### Route conventions
|
||||||
|
|
||||||
@@ -186,35 +188,34 @@ All Go services instrumented with Elastic APM and Prometheus metrics. Traefik ha
|
|||||||
## Gotchas and Non-Obvious Details
|
## Gotchas and Non-Obvious Details
|
||||||
|
|
||||||
1. **Config library**: Services use `knadh/koanf` with TOML parser, not `fig`. Tags are `koanf:"field-name"`.
|
1. **Config library**: Services use `knadh/koanf` with TOML parser, not `fig`. Tags are `koanf:"field-name"`.
|
||||||
2. **gRPC connection lifecycle**: Connections are lazy — created on first call, not at startup. A background goroutine closes and nils connections after 2 minutes of inactivity, triggering reconnection.
|
2. **gRPC connection lifecycle**: Connections are lazy — created on first RPC. Active calls prevent idle closure; peers close after the configured inactivity timeout (2-minute default) and reconnect on the next call.
|
||||||
3. **Enum codegen**: `api/service/servicesenum_enumer.go` is auto-generated via `//go:generate go run github.com/alvaroloes/enumer`. Adding enum values requires `go generate`.
|
3. **Peer mapping**: `infrastructure/grpcclient` maps configured peers explicitly; the former reflection/enum generator is removed.
|
||||||
4. **Swagger docs**: Generated by `swag init` and served via gin-swagger. URL adapts per environment (prod → `api.darano.ir`, dev → `dev.api.darano.ir`, local → `localhost:<port>`).
|
4. **Swagger docs**: Generated by `swag init` and served via `interface/http`. URL adapts per environment (prod → `api.darano.ir`, dev → `dev.api.darano.ir`, local → `localhost:<port>`).
|
||||||
5. **Multi-service wallet**: The wallet binary serves 5 sub-services. `make run` kills existing processes matching the service name pattern via `pgrep | xargs kill` before starting.
|
5. **Multi-service wallet**: The wallet binary serves 5 sub-services. `make run` kills existing processes matching the service name pattern via `pgrep | xargs kill` before starting.
|
||||||
6. **Concurrent dev**: Running multiple `make dev-*` targets simultaneously requires the `flock` serialization in the Makefile. Using `make -j` without flock will corrupt the build.
|
6. **Concurrent dev**: Running multiple `make dev-*` targets simultaneously requires the `flock` serialization in the Makefile. Using `make -j` without flock will corrupt the build.
|
||||||
7. **Proto stubs excluded from watchers**: `.air.toml` excludes `domain/stub/` from file watching. Air also excludes `swagger/` and `testdata/`.
|
7. **Proto stubs excluded from watchers**: `.air.toml` excludes `domain/stub/` from file watching. Air also excludes `swagger/` and `testdata/`.
|
||||||
8. **API testing requests**: `api/req/` contains JS files for API request testing (axios-based) — not part of the app, useful for manual testing.
|
8. **API testing requests**: `api/req/` contains JS files for API request testing (axios-based) — not part of the app, useful for manual testing.
|
||||||
9. **Django Admin**: Uses `unfold` theme (AdminPanel admin customizations in `sites.py` and `unfoldconf.py`).
|
9. **Django Admin**: Uses `unfold` theme (AdminPanel admin customizations in `sites.py` and `unfoldconf.py`).
|
||||||
10. **Proto generation for AdminPanel**: Generates into root directories (`base/`, `wallet/`, etc.) then deletes them with `rm -rf`. The betterproto generator outputs Python classes directly.
|
10. **Proto generation for AdminPanel**: `make proto` uses the adjacent local `proto/` checkout and generates only the active Base/Auth/Wallet BetterProto message subset into `src/stub/`.
|
||||||
|
|
||||||
## AdminPanel Deep Dive
|
## AdminPanel Deep Dive
|
||||||
|
|
||||||
- **Architecture**: Django admin panel that bypasses all Go backend services. Connects directly to `core_db` (same Postgres as Go services) for read/write. Uses Django DB routers in `src/adminpanel/db/routers.py` to route `coreLogic` models to `core_db` and other apps to `default`.
|
- **Architecture**: Django admin panel that reads `core_db` directly for fast projections. Unmanaged models are read-only by default; the Assets admin sends authenticated typed commands to Wallet instead of writing the database. Django DB routers route `coreLogic` reads to `core_db` and other apps to `default`.
|
||||||
- **Models**: `src/coreLogic/models.py` contains `managed = False` Django models — manual replicas of Go GORM models generated via `inspectdb`. **Not auto-generated from protos.** `make proto` generates betterproto Python stubs separately but Django models are maintained by hand. **Never edit models.py manually** — it drifts from Go services.
|
- **Models**: `src/coreLogic/models.py` contains `managed = False` Django models — manual replicas of Go GORM models generated via `inspectdb`. **Not auto-generated from protos.** `make proto` generates betterproto Python stubs separately but Django models are maintained by hand. **Never edit models.py manually** — it drifts from Go services.
|
||||||
- **Admin classes**: `src/coreLogic/admin/` — 17 admin files (`asset.py`, `wallets.py`, `market.py`, etc.). All inherit from `MultiDBModelAdmin` in `src/utils/base_admin.py` which handles: multi-database writes (`using="core_db"`), soft deletes via `deleted_at`, asset-level permission filtering, and Jalali date widgets.
|
- **Admin classes**: `src/coreLogic/admin/` — admin files inherit from `MultiDBModelAdmin` in `src/utils/base_admin.py`, which routes reads to `core_db`, applies asset-level filters/Jalali widgets, and makes unmanaged projections fail closed for add/change/delete. Assets opt into service-backed mutations only.
|
||||||
- **Permission system**: `src/usermapper/user_perm.py` + `src/coreLogic/acl.py` — admin users get asset-level access control. `save_model` checks `user_perm.can_access_asset()` before allowing writes.
|
- **Permission system**: `src/usermapper/user_perm.py` + `src/coreLogic/acl.py` — admin users get asset-level access control. Asset service commands enforce the same access decision before dispatch.
|
||||||
- **Key gotchas**:
|
- **Key gotchas**:
|
||||||
- `check_token_policy()` in `admin/asset.py:161` duplicates validation from wallet service. Changes to asset validation must be made in **both** places.
|
- Asset policy and default metadata are owned by Wallet's `application/adminasset`; do not recreate them in Django.
|
||||||
- `GENERIC_ASSET_META_VALUE` in `admin/asset.py:31` is a hardcoded JSON blob — if the wallet service changes asset metadata structure, this must be updated too.
|
- The Wallet admin client requires matching AdminPanel `WALLET_ADMIN_GRPC_TOKEN` and internal-wallet `[admin-assets].token` configuration.
|
||||||
- The router has a typo: `no_migartion` → should be `no_migration`.
|
- All `coreLogic` models are read via `core_db` directly. Adding a mutation requires an explicit typed owning-service workflow; never opt an unmanaged model into direct ORM writes.
|
||||||
- All `coreLogic` models are read via `core_db` directly. **Any admin write bypasses Go services** — no trustline updates, no blockchain operations, no validation from wallet/market services.
|
|
||||||
|
|
||||||
## Ongoing Refactoring: DDD / Clean Architecture
|
## Ongoing Refactoring: DDD / Clean Architecture
|
||||||
|
|
||||||
This repository is being migrated to a unified Domain-Driven Design / Clean Architecture. See [`REFACTORING-PLAN.md`](REFACTORING-PLAN.md) for the full plan.
|
This repository is being migrated to a unified Domain-Driven Design / Clean Architecture. See [`REFACTORING-PLAN.md`](REFACTORING-PLAN.md) for the full plan.
|
||||||
|
|
||||||
**Go services current state**: `api/` uses koanf, `auth/` uses fig with `usecase/`, `wallet/` uses fig with `core/walletImp/` mixing gRPC server and business logic. Config libraries differ. Domain entities and persistence models are conflated.
|
**Go services current state**: API, Auth, and Wallet configuration and architecture phases are complete on `feat/refactor-v1`; use the refactoring tracker and audit for the current package boundaries and verification evidence.
|
||||||
|
|
||||||
**AdminPanel current state**: Direct DB access to `core_db` with no gRPC layer. Business logic duplicated in Django admin classes (`check_token_policy`, `auto_gen` instead of delegating to Go services). `managed = False` models drift from Go GORM models.
|
**AdminPanel current state**: Direct DB reads remain, while unmanaged projections fail closed for writes. Asset upsert/deactivation uses an authenticated Wallet gRPC adapter; duplicated asset policy and metadata generation have been removed from Django. `managed = False` models can still drift from Go persistence models and must remain projection-only.
|
||||||
|
|
||||||
**Target**: All Go services follow `domain/` → `application/` → `infrastructure/` → `interface/` with inward dependencies. AdminPanel routes writes through gRPC to Go services while keeping reads from DB for performance.
|
**Target**: All Go services follow `domain/` → `application/` → `infrastructure/` → `interface/` with inward dependencies. AdminPanel routes writes through gRPC to Go services while keeping reads from DB for performance.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
# Darano refactoring final migration report
|
||||||
|
|
||||||
|
Date: 2026-09-01
|
||||||
|
Branch: `feat/refactor-v1`
|
||||||
|
Authoritative tracker: `REFACTORING-TODO.md`
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
The planned refactoring is complete. There are no `TODO`, `STARTED`, or `FAILED`
|
||||||
|
tasks in the actionable tracker. Historical `CHANGED` entries preserve explicit
|
||||||
|
scope decisions and completed task splits.
|
||||||
|
|
||||||
|
Active repositories are API, Auth, Wallet, AdminPanel, Proto, and GL. UI, Docs,
|
||||||
|
and DevOps were excluded from the architecture refactor by scope decision and were
|
||||||
|
not modified during the final phase.
|
||||||
|
|
||||||
|
## Delivered architecture
|
||||||
|
|
||||||
|
- API owns the public HTTP boundary under `interface/http`, depends on an
|
||||||
|
application upstream port, and uses explicitly composed lazy gRPC clients.
|
||||||
|
- Auth configuration is injected; domain/application boundaries cover OTP,
|
||||||
|
session/JWT, identity, periodic identity validation, and permissions; persistence
|
||||||
|
and provider implementations are infrastructure-owned.
|
||||||
|
- Wallet uses exact scale-7 domain money, application-owned wallet/transaction,
|
||||||
|
market, alert, stream, locking, and asset-administration workflows, explicit
|
||||||
|
process composition, durable transaction/ledger outboxes, and interface-owned
|
||||||
|
adapters.
|
||||||
|
- GL is an independent immutable double-entry service with scale-18 audit amounts,
|
||||||
|
idempotent append/reversal, reconciliation, recovery, explorer, and load coverage.
|
||||||
|
- Publisher-backed ICO settlement and all transaction-type event routes use the
|
||||||
|
owning Wallet/Market workflows with durable, idempotent delivery.
|
||||||
|
- Federation coupling and wallet creation by federation were removed; ownership is
|
||||||
|
`user_id -> identity_id -> wallet_id`, with wallets remaining asset-scoped.
|
||||||
|
- AdminPanel retains direct SQL reads for projections. Unmanaged projections fail
|
||||||
|
closed for writes; Assets alone use authenticated typed Wallet upsert/deactivate
|
||||||
|
commands. Duplicate Django wallet policy and secondary persistence signals are gone.
|
||||||
|
- Proto changes are additive where compatibility was required, and active generated
|
||||||
|
consumers are committed and reproducible.
|
||||||
|
|
||||||
|
## Shared-type decision
|
||||||
|
|
||||||
|
`SHARED-TYPES-EVALUATION.md` concludes that no new shared source package is safe:
|
||||||
|
|
||||||
|
- Wallet uses scale 7 with Stellar and `numeric(23,7)` semantics.
|
||||||
|
- GL uses precision 38/scale 18 with canonical immutable-journal semantics.
|
||||||
|
- deployed IDs mix signed database keys, unsigned legacy contract fields, Auth-owned
|
||||||
|
regulated identifiers, and opaque GL strings.
|
||||||
|
|
||||||
|
The approved boundary remains canonical base-10 decimal strings plus explicit
|
||||||
|
adapter conversions. Services do not import another service's domain package.
|
||||||
|
|
||||||
|
## Final corrections found by verification
|
||||||
|
|
||||||
|
- API commit `0074e91` regenerates its Wallet contract consumer.
|
||||||
|
- Auth commit `2c8a0b1` regenerates its Wallet contract consumer.
|
||||||
|
- Wallet commit `3b898e1` makes the duplicate-event integration assertion wait for
|
||||||
|
the first inbox success transition. The previous test could publish its duplicate
|
||||||
|
before the first handler completed; 20 race-enabled repetitions and the full race
|
||||||
|
suite pass after the correction.
|
||||||
|
|
||||||
|
These changes are scoped to generated outputs or test synchronization. No unrelated
|
||||||
|
working-tree changes were absorbed.
|
||||||
|
|
||||||
|
## Final verification
|
||||||
|
|
||||||
|
| Repository | Verification |
|
||||||
|
|---|---|
|
||||||
|
| Proto | Buf lint, build, and breaking check against the prior commit pass. |
|
||||||
|
| API | Proto and Swagger generation; `go test ./...`; race tests; vet; build; whitespace checks pass. |
|
||||||
|
| Auth | Proto generation; `go test ./...`; race tests; vet; build; whitespace checks pass. |
|
||||||
|
| Wallet | Proto generation; normal and race tests; vet; build; focused duplicate-event race test repeated 20 times; whitespace checks pass. |
|
||||||
|
| GL | Templ/proto generation; normal and race tests; vet; build pass. The localhost `httptest` case required normal socket permission rather than the restricted sandbox. |
|
||||||
|
| AdminPanel | Local BetterProto generation; 13 focused boundary tests; Django system checks; Python compilation; whitespace checks pass. |
|
||||||
|
|
||||||
|
API/Auth/Wallet/GL/AdminPanel/Proto are clean on `feat/refactor-v1` after their final
|
||||||
|
commits. The coordination repository contains only this final documentation change
|
||||||
|
until its handoff commit is created.
|
||||||
|
|
||||||
|
## Required deployment configuration
|
||||||
|
|
||||||
|
Asset administration is fail-closed. Configure matching secrets:
|
||||||
|
|
||||||
|
- AdminPanel: `WALLET_ADMIN_GRPC_TOKEN`
|
||||||
|
- Internal Wallet: `[admin-assets].token`
|
||||||
|
|
||||||
|
Optional AdminPanel settings:
|
||||||
|
|
||||||
|
- `WALLET_ADMIN_GRPC_ADDRESS` (default `127.0.0.1:8500`)
|
||||||
|
- `WALLET_ADMIN_GRPC_TIMEOUT` (default 5 seconds)
|
||||||
|
|
||||||
|
The internal Wallet schedule/config files remain environment-owned and ignored where
|
||||||
|
previously established; deploy secrets through the existing configuration mechanism.
|
||||||
|
|
||||||
|
## Known external/baseline conditions
|
||||||
|
|
||||||
|
- The Darano Go proxy previously returned long `504` responses during cold Docker
|
||||||
|
dependency downloads for API/Auth/Wallet. Native generation, tests, vet, and builds
|
||||||
|
pass; the final phase did not alter registry policy or add a public fallback.
|
||||||
|
- Django deploy checks still depend on production-provided secret, TLS redirect,
|
||||||
|
secure cookie, CSRF, HSTS, and DEBUG settings. Normal system checks pass.
|
||||||
|
- Legacy public Wallet/Market protobuf money remains `double` for compatibility.
|
||||||
|
New exact internal financial boundaries must use canonical decimal strings.
|
||||||
|
|
||||||
|
## Handoff
|
||||||
|
|
||||||
|
Use `REFACTORING-TODO.md`, `REFACTORING-AUDIT.md`, this report, and `MEMORY.md` as
|
||||||
|
the continuation sources. All implementation tasks are complete; future work should
|
||||||
|
be opened as a new scoped task rather than reopening the finished migration tracker.
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
# Darano project memory
|
||||||
|
|
||||||
|
Updated: 2026-08-30
|
||||||
|
|
||||||
|
## Product and domain
|
||||||
|
|
||||||
|
Darano is a real-world-asset tokenization platform. Bank Mellat is the main customer context and real estate is the primary asset class. User flows include wallets and locked balances, transaction history, bank accounts, referrals, legal agreements/contracts, maker/taker trading, ICO purchases, bank and Kuknos deposit identification, IPG deposits, IRT withdrawals, third-party collateral locks, and optional SMS/TOTP/email 2FA.
|
||||||
|
|
||||||
|
User transaction requests are event-driven. No automatic transaction-acceptance policy exists yet.
|
||||||
|
|
||||||
|
## Sources of truth and availability
|
||||||
|
|
||||||
|
- The append-only General Ledger (GL) is the primary source of truth.
|
||||||
|
- Kuknos (Stellar 18+ compatible) is the secondary source of truth.
|
||||||
|
- A normal financial transaction requires both GL and Kuknos.
|
||||||
|
- If GL is unavailable, all financial transactions halt. Health becomes `critical` and the incident is emitted through structured/OTel-compatible logs.
|
||||||
|
- Kuknos failure also halts transactions while enabled. An administrator may explicitly disable Kuknos by admin toggle or configuration; this is never an automatic failover.
|
||||||
|
- The local Docker stack uses the explicit `DARANO_KUKNOS_ENABLED=false` configuration because the test Horizon endpoint returns 403/timeouts. GL remains mandatory.
|
||||||
|
|
||||||
|
## Implemented architecture
|
||||||
|
|
||||||
|
- Wallet contains a financial availability gate covering GL and Kuknos.
|
||||||
|
- Transaction event outbox/inbox/deadbox processing is present for event-driven requests.
|
||||||
|
- GL writes are append-only and wallet financial work fails closed when GL is unavailable.
|
||||||
|
- API `/` health reports the financial component and returns HTTP 503 with `critical` status when unavailable.
|
||||||
|
- Kuknos streaming pauses when the manual Kuknos switch is disabled.
|
||||||
|
- Concurrent wallet-role database migrations are serialized with a PostgreSQL transaction advisory lock.
|
||||||
|
- API configuration loading now accepts absolute paths.
|
||||||
|
|
||||||
|
## Local Docker Desktop stack
|
||||||
|
|
||||||
|
Definition: `DevOps/local/compose.yml`
|
||||||
|
|
||||||
|
Use Docker Desktop, not OrbStack.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose -f DevOps/local/compose.yml build
|
||||||
|
docker compose -f DevOps/local/compose.yml up -d --no-build
|
||||||
|
docker compose -f DevOps/local/compose.yml ps -a
|
||||||
|
```
|
||||||
|
|
||||||
|
Local endpoints:
|
||||||
|
|
||||||
|
- API: `http://localhost:3000`
|
||||||
|
- UI: `http://localhost:3001`
|
||||||
|
- AdminPanel: `http://localhost:8080`
|
||||||
|
- Auth: `localhost:8100`
|
||||||
|
- Wallet: `localhost:8200`
|
||||||
|
- Market: `localhost:8300`
|
||||||
|
- Alert: `localhost:8400`
|
||||||
|
- Internal wallet: `localhost:8500`
|
||||||
|
- GL: `localhost:8600`
|
||||||
|
- PostgreSQL: `localhost:5432`
|
||||||
|
- Redis: `localhost:6379`
|
||||||
|
- RabbitMQ: `localhost:5672`, management `localhost:15672`
|
||||||
|
|
||||||
|
The UI uses `http://api:3000` for server-side container requests and `http://localhost:3000` for browser requests.
|
||||||
|
|
||||||
|
## Package registries
|
||||||
|
|
||||||
|
- Go: `https://go.reg.darano.ir`
|
||||||
|
- Python: `https://pypi.reg.darano.ir/simple/`
|
||||||
|
|
||||||
|
Dockerfiles were updated to use these defaults. AdminPanel retains one lockfile-pinned Kavenegar Git dependency from GitHub. UI npm packages still use the public npm registry.
|
||||||
|
|
||||||
|
## Validation performed
|
||||||
|
|
||||||
|
- GL, API, auth, wallet, AdminPanel, and UI Docker images built successfully on Docker Desktop ARM64.
|
||||||
|
- API absolute config-path test passes.
|
||||||
|
- Wallet infrastructure config and PostgreSQL repository tests pass.
|
||||||
|
- Concurrent wallet roles remained running after the migration serialization fix.
|
||||||
|
- With Kuknos enabled and unavailable, GL stayed ready while readiness became critical, HTTP health returned 503, logs recorded the reason, and event delivery halted as designed.
|
||||||
|
|
||||||
|
## Known frontend warnings
|
||||||
|
|
||||||
|
- `ui/.eslintrc.json` is malformed/empty, so the production build reports an ESLint configuration warning.
|
||||||
|
- `next.config.mjs` passes obsolete `fileExtensions` to `next-images`.
|
||||||
|
- Buf reports duplicate generated TypeScript filenames but completes the UI build.
|
||||||
|
|
||||||
|
## Repository rule
|
||||||
|
|
||||||
|
All changed project repositories are kept on `feat/refactor-v1`. Clean auxiliary repositories that already use another branch were not modified.
|
||||||
|
|
||||||
|
## Cross-machine continuation handoff (2026-08-30)
|
||||||
|
|
||||||
|
All committed work was pushed. `api`, `auth`, `wallet`, `proto`, and `dev-procfile` are clean on `feat/refactor-v1` and synchronized with `origin`. API's branch diverged from the remote and was safely merged in `32c3953`; the refactored configuration layout was retained, obsolete legacy `config/` and `Dockerfile` conflict artifacts stayed removed, and `go test ./...` passes.
|
||||||
|
|
||||||
|
### Recently completed
|
||||||
|
|
||||||
|
- Federation was removed from Wallet/Auth/API and the shared wallet protobuf. The intended ownership remains `user_id → identity_id → wallet_id`, with wallets asset-scoped. Deployed databases still need their separate legacy federation column/table migration.
|
||||||
|
- Auth refactoring tasks `A001`–`A009` are complete, including configurable periodic identity validation.
|
||||||
|
- Wallet `W001`–`W013` are complete. The final W005–W012 series ends at `240b8d0` on `feat/refactor-v1`.
|
||||||
|
- Recent Wallet completion commits include `03da6fd` atomic trustline transaction persistence, `c7f442a` failed IPG fulfillment recording, `ae0b185` canceled-maker balance release, `ca2dc50` synchronous settlement, `fbca6fa` stream application service, `14c5d35` lock persistence workflow, `200d6d6` market lifecycle, `d91d51b` transaction balance processor, and `240b8d0` final interface boundaries.
|
||||||
|
- API `G001`–`G008` are complete. The compatibility inventory begins at `95c4264`; the final removal of superseded packages is `31e3043`. Upstream clients live in `infrastructure/grpcclient`, HTTP adapters live in `interface/http`, and `cmd/apiRuntime` owns explicit composition.
|
||||||
|
|
||||||
|
### Wallet completion state
|
||||||
|
|
||||||
|
Use `REFACTORING-TODO.md` and `REFACTORING-AUDIT.md` as the authoritative detailed tracker. No Wallet refactoring task remains open. The active Vandar PSP interface has verification/settlement but no refund/reversal operation; post-settlement fulfillment failures are persisted as failed transactions rather than calling a fabricated provider API.
|
||||||
|
|
||||||
|
Final Wallet verification on 2026-08-31: protobuf regeneration produced no diff; `go test ./...`, `go test -race ./...`, `go vet ./...`, and `go build ./...` all passed.
|
||||||
|
|
||||||
|
### API completion state
|
||||||
|
|
||||||
|
No API refactoring task remains open. Final API verification on 2026-08-31: protobuf and Swagger regeneration produced no diff; `go test ./...`, `go test -race ./...`, `go vet ./...`, and `go build ./...` all passed. Swagger regeneration requires `GOCACHE=/tmp/darano-api-go-cache` in this environment.
|
||||||
|
|
||||||
|
### AdminPanel/protobuf completion state
|
||||||
|
|
||||||
|
`P001`–`P010` and `R001`–`R003` are complete. AdminPanel still reads service-owned tables directly, but every unmanaged model is read-only unless explicitly service-backed. Assets write through authenticated Wallet gRPC upsert/deactivate commands; prices and every other legacy mutation/import/inline/bulk path are disabled. Configure matching `WALLET_ADMIN_GRPC_TOKEN` in AdminPanel and `[admin-assets].token` in the internal-wallet configuration, plus the optional `WALLET_ADMIN_GRPC_ADDRESS` and `WALLET_ADMIN_GRPC_TIMEOUT` values. AdminPanel protobuf generation now uses the adjacent local `proto/` checkout and BetterProto 2.
|
||||||
|
|
||||||
|
### Final refactoring completion state (2026-09-01)
|
||||||
|
|
||||||
|
`F001`–`F005` are complete and the authoritative tracker has no actionable remaining task. `SHARED-TYPES-EVALUATION.md` records why Wallet scale-7 money, GL scale-18 money, legacy numeric IDs, Auth identifiers, and opaque GL IDs remain bounded-context types. `FINAL-MIGRATION-REPORT.md` records the final architecture, verification matrix, deployment configuration, known external conditions, and handoff.
|
||||||
|
|
||||||
|
Final verification regenerated every active consumer and found two missing checked-in consumers plus one race-test synchronization issue. API `0074e91`, Auth `2c8a0b1`, and Wallet `3b898e1` contain those corrections. Proto lint/build/breaking, all active Go normal/race/vet/build gates, Wallet's focused 20-run race test, AdminPanel's 13 focused tests/checks/compilation, and reproducible generation pass.
|
||||||
|
|
||||||
|
### Commands and cautions
|
||||||
|
|
||||||
|
- Prefix shell commands with `rtk` as required by `/home/navid/.codex/RTK.md`.
|
||||||
|
- Use `rtk env GOCACHE=/tmp/darano-wallet-go-cache go test ./...` from `wallet/`; the default Go build cache is not writable in this environment.
|
||||||
|
- Use `rtk env GOCACHE=/tmp/darano-api-go-cache go test ./...` from `api/`.
|
||||||
|
- Use `apply_patch` for edits. Do not hand-edit generated protobuf stubs; regenerate through the service build/proto workflow.
|
||||||
|
- Preserve unrelated worktree changes. Do not force-push.
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
# Go services — air builds on first run and rebuilds+restarts on any .go change
|
# Go services — air builds on first run and rebuilds+restarts on any .go change
|
||||||
api: cd api && sleep 2 && air
|
api: cd api && sleep 2 && air
|
||||||
auth: cd auth && air
|
auth: cd auth && air
|
||||||
|
gl: cd GL && air
|
||||||
|
|
||||||
# Wallet binary hosts multiple sub-services; each gets its own air config + cfg file.
|
# Wallet binary hosts multiple sub-services; each gets its own air config + cfg file.
|
||||||
# All five run `make build` independently — Go's build cache serialises concurrent builds safely.
|
# All five run `make build` independently — Go's build cache serialises concurrent builds safely.
|
||||||
@@ -14,7 +15,7 @@ wallet-stream: cd wallet && air -c .stream.air.toml
|
|||||||
admin: cd AdminPanel && .venv/bin/python src/manage.py runserver 0.0.0.0:8080 --traceback
|
admin: cd AdminPanel && .venv/bin/python src/manage.py runserver 0.0.0.0:8080 --traceback
|
||||||
|
|
||||||
# Next.js — yarn dev includes HMR out of the box; buf generate runs automatically before dev server
|
# Next.js — yarn dev includes HMR out of the box; buf generate runs automatically before dev server
|
||||||
ui: cd ui && yarn dev -H 0.0.0.0 -p 3000
|
ui: cd ui && pnpm dev -H 0.0.0.0 -p 3000
|
||||||
|
|
||||||
# Mkdocs - Darano and Dezone documnetaitons
|
# Mkdocs - Darano and Dezone documnetaitons
|
||||||
docs: cd docs && make dev
|
docs: cd docs && make dev
|
||||||
|
|||||||
@@ -41,15 +41,15 @@ cd darano
|
|||||||
|
|
||||||
git clone --branch feat/refactor-v1 git@git.darano.ir:Kahroba/AdminPanel.git AdminPanel
|
git clone --branch feat/refactor-v1 git@git.darano.ir:Kahroba/AdminPanel.git AdminPanel
|
||||||
git clone --branch m2 git@git.darano.ir:Kahroba/DevOps.git DevOps
|
git clone --branch m2 git@git.darano.ir:Kahroba/DevOps.git DevOps
|
||||||
git clone --branch dev git@git.darano.ir:Kahroba/GL.git GL
|
git clone --branch feat/refactor-v1 git@git.darano.ir:Kahroba/GL.git GL
|
||||||
git clone --branch main git@git.darano.ir:KuknosNode/Scripts.git Kuknos-Node-scripts
|
git clone --branch main git@git.darano.ir:KuknosNode/Scripts.git Kuknos-Node-scripts
|
||||||
git clone --branch dev git@git.darano.ir:Kahroba/alert.git alert
|
git clone --branch dev git@git.darano.ir:Kahroba/alert.git alert
|
||||||
git clone --branch main git@git.darano.ir:Kahroba/api.git api
|
git clone --branch feat/refactor-v1 git@git.darano.ir:Kahroba/api.git api
|
||||||
git clone --branch feat/refactor-v1 git@git.darano.ir:Kahroba/auth.git auth
|
git clone --branch feat/refactor-v1 git@git.darano.ir:Kahroba/auth.git auth
|
||||||
git clone --branch main git@git.darano.ir:Kahroba/dev-procfile.git dev-procfile
|
git clone --branch feat/refactor-v1 git@git.darano.ir:Kahroba/dev-procfile.git dev-procfile
|
||||||
git clone --branch dev git@git.darano.ir:Kahroba/docs.git docs
|
git clone --branch dev git@git.darano.ir:Kahroba/docs.git docs
|
||||||
git clone --branch feat/refactor-v1 git@git.darano.ir:Kahroba/proto.git proto
|
git clone --branch feat/refactor-v1 git@git.darano.ir:Kahroba/proto.git proto
|
||||||
git clone --branch fix/contact-us git@git.darano.ir:Kahroba/ui.git ui
|
git clone --branch dev git@git.darano.ir:Kahroba/ui.git ui
|
||||||
git clone --branch feat/refactor-v1 git@git.darano.ir:Kahroba/wallet.git wallet
|
git clone --branch feat/refactor-v1 git@git.darano.ir:Kahroba/wallet.git wallet
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -209,6 +209,121 @@ Global config removal remains the separate follow-up `C002`.
|
|||||||
- Wallet vet remains limited to three findings reproduced in the untouched baseline: logger unreachable code, alert timeout cancel, and protobuf lock copying in queue JSON marshaling.
|
- Wallet vet remains limited to three findings reproduced in the untouched baseline: logger unreachable code, alert timeout cancel, and protobuf lock copying in queue JSON marshaling.
|
||||||
- Wallet commit: `7958530 refactor(wallet): move config loading to infrastructure`.
|
- Wallet commit: `7958530 refactor(wallet): move config loading to infrastructure`.
|
||||||
|
|
||||||
|
### `C004` — wallet configuration injection
|
||||||
|
|
||||||
|
- Configuration is loaded once by each Cobra command and carried explicitly through command context into repository setup, service constructors, gRPC listeners, profiling, availability monitoring, ledger and transaction-event workers, cron jobs, and Stellar initialization.
|
||||||
|
- Repository, domain/use-case, market, alert, wallet lifecycle, financial, SMS, logger, and Stellar dependencies now receive either the full configuration or narrow values at construction/call boundaries.
|
||||||
|
- Stellar transaction fees, network passphrase, gas policy, deterministic key material, and distributor secret are injected into the adapter; focused tests verify the initialized client retains every supplied value.
|
||||||
|
- Removed the temporary `wallet/config` compatibility facade and its process-global `Cfg`; production source has no active global configuration reads or legacy config imports.
|
||||||
|
- Full `go test ./...`, `go test -race ./...`, `go vet ./...`, and `go build ./...` pass with the isolated Go cache.
|
||||||
|
- Wallet implementation was committed in reviewable slices from `f507637` through `4d192a6`, including final Stellar (`53df96a`), logger (`1b3ffc8`), and command-root (`4d192a6`) injection commits.
|
||||||
|
|
||||||
|
### `C005`/`C006` — API configuration ownership and injection
|
||||||
|
|
||||||
|
- Moved API configuration types and pure koanf/TOML loading into `api/infrastructure/config`, preserving the default IPG callback and UI error URLs and file-overrides-default behavior.
|
||||||
|
- The command boundary loads configuration once and passes it into logger, gRPC service composition, HTTP handlers, middleware, Swagger selection, profiling, and upstream clients.
|
||||||
|
- Removed the API `config.Cfg` singleton and legacy `gateway/config` package; source scans show no active global configuration reads or legacy imports.
|
||||||
|
- API `go test ./...`, `go test -race ./...`, `go vet ./...`, and `go build ./...` pass. Existing unrelated Swagger and module-file work remains uncommitted and preserved.
|
||||||
|
- API commit: `44d56d3 refactor(api): move and inject configuration`.
|
||||||
|
|
||||||
|
### `L009`/`L010` — GL reconciliation and recovery verification
|
||||||
|
|
||||||
|
- GL provides read-only reconciliation over sealed journals, detecting invalid journals and duplicate source transaction/version identities without mutating ledger state.
|
||||||
|
- External settlement evidence can be compared repeatedly against GL journals to report missing evidence, duplicate evidence, and blockchain network/hash mismatches.
|
||||||
|
- The read-only explorer reconstructs account and holder balances from immutable entries and exposes journal, transaction-hash, account, and balance reads for disaster recovery.
|
||||||
|
- Replay is bounded and idempotent; immutable journal validation, canonical payload hashes, transactional rollback, sealed-journal checks, and database uniqueness constraints prevent duplicate or partial postings.
|
||||||
|
- Conservation and concurrent transfer behavior are exercised by the fixed redistribution load scenario; GL full tests, race tests, vet, and build pass. The sandbox initially blocked localhost sockets for an existing `httptest` test; the same verification passed with localhost access enabled.
|
||||||
|
- GL implementation commits: `3f5fd86`, `b14c5e2`, and `d5c9b33`; verification completed on `2026-08-30`.
|
||||||
|
|
||||||
|
### Auth periodic identity validation extension
|
||||||
|
|
||||||
|
- Added `Identity.LastChecked` for the biweekly phone/national-ID validation and `Identity.LastBirthDateChecked` for the monthly national-ID/birthdate validation; Auth's existing startup auto-migration adds the indexed columns.
|
||||||
|
- Added a local-midnight scheduler job with configurable cron expression and independent validation intervals (defaults: 14 days and 30 days).
|
||||||
|
- The job retries failed people on a later run by updating timestamps only after successful validation and refresh; it reports checked, skipped, and failed counts without disabling or overwriting an identity on a failed provider check.
|
||||||
|
- `DISABLE_PRIODICAL_IDENTITY_VALIDATION=1` (the requested spelling; `0`, `true`, and `false` are also accepted) disables the job. The nested `periodic-identity-validation` config section controls schedule, intervals, and the file-level disabled flag.
|
||||||
|
- Auth full tests, race tests, vet, and build pass; implementation committed as `9bc9cca`.
|
||||||
|
|
||||||
|
### `A001` — Auth RPC and dependency migration map
|
||||||
|
|
||||||
|
| RPC / operation | Current operation | Persistence / external dependencies | Target application boundary |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `AuthorizationSrvHealth`, `InternalAuthorizationSrvHealth` | readiness check | PostgreSQL ping | health use case + gRPC adapter |
|
||||||
|
| `CheckIAM` | authenticate request identity and load roles/identity | User, Identity, Role, RolePermission, Redis cache | authorization use case |
|
||||||
|
| `SendLoginOTP`, `LoginWithOTP`, `GetAccessTokenByRefreshToken` | OTP issuance, login, refresh-token rotation | User, Session, OTP templates, Redis, Kavenegar, JWT keys | authentication/OTP use cases |
|
||||||
|
| `GetUserPermission`, `InitPermissionsForRoutes`, `InitAdminRole` | route/role/permission bootstrap and lookup | Permission, Role, RolePermission, User, Redis | permission use case |
|
||||||
|
| `GetIdentity`, `UpdateIdentity`, `GetUserIdentityBasic`, `GetUserIAM`, `GetUser` | identity read/update and IAM projection | User, Identity, Redis, Shahkar provider, Pecco/Zohal/Ehraz, Internal Wallet | identity use case |
|
||||||
|
| `GetBankInfoList`, `UpdateBankInfo`, `RemoveBankInfo` | IBAN verification and bank-info lifecycle | BankInfo, Identity, transaction boundary, Zohal | bank-information use case |
|
||||||
|
| `ProcessTFAReq`, `InitTFAReq`, `CheckTFACode` | TFA state/code lifecycle | Session, Redis, Kavenegar, OTP templates | TFA use case |
|
||||||
|
| `LookUpName` | resolve mobile/national ID/public key to recipient | direct SQL join of User/Identity | recipient lookup use case |
|
||||||
|
| `FetchBasicUserInfoList` | list basic user identities for internal consumers | User, Identity | internal user-query use case |
|
||||||
|
| `DeleteCache` | invalidate authorization/identity cache | Redis | cache management operation |
|
||||||
|
| periodic identity validation | scheduled phone/national-ID and national-ID/birthdate refresh | User, Identity, Shahkar/person providers | scheduled identity-validation use case |
|
||||||
|
|
||||||
|
The current composition root is `cmd/serve.go`; `repository.System` aggregates PostgreSQL, Redis, and upstream service ports, while `usecase.useCase` currently implements both generated gRPC server interfaces. External provider selection is configuration-driven (`ShahkarProvider`), and the Wallet/Notification clients are gRPC dependencies. This map is the baseline for A002–A008 package extraction.
|
||||||
|
|
||||||
|
### `A002` — Auth domain entities and repository ports
|
||||||
|
|
||||||
|
- Added `auth/domain/model` with transport/persistence-independent User, Identity, Session, Permission, Role, RolePermission, and BankInfo entities.
|
||||||
|
- Added validated `NationalID`, `MobileNumber`, and `BirthDate` value objects plus domain-level user status values.
|
||||||
|
- Added stable domain error vocabulary independent of gRPC status codes.
|
||||||
|
- Added `auth/domain/ports` repository and cache interfaces using only standard library types and domain models.
|
||||||
|
- Focused value-object/domain tests and the full Auth test suite pass; commits `32f182b` and `d292822`.
|
||||||
|
- Existing `domain/db` remains the legacy persistence mapping until A003 introduces explicit infrastructure mappings.
|
||||||
|
|
||||||
|
### `A003` — Auth persistence migration checkpoint
|
||||||
|
|
||||||
|
- Added `auth/infrastructure/persistence` with explicit User and Identity mappings between legacy GORM records and the pure domain model.
|
||||||
|
- Mapping validates domain value objects at the boundary and preserves timestamps, roles, public keys, identity validation timestamps, and birth-date representation.
|
||||||
|
- Focused mapping tests and the full Auth test suite pass; commit `58f6a43`.
|
||||||
|
- A003 remains in progress: PostgreSQL/Redis adapter ownership and use-case integration still need to move out of the legacy `repository/db` composition.
|
||||||
|
- Added `auth/infrastructure/postgres` and `auth/infrastructure/redis` composition boundaries and switched `cmd/serve.go` to use them; the legacy adapters remain wrapped behind these boundaries pending per-repository port integration (`8ce3727`).
|
||||||
|
- Added domain-port adapters for User, Identity, and Cache that translate legacy repository records at the infrastructure edge and satisfy `domain/ports`; mapping, full tests, and infrastructure vet pass in `7d9dd25`.
|
||||||
|
- Added mappings and domain-port adapters for Session, Permission, Role, RolePermission, BankInfo, and OTPTemplate, completing the explicit persistence boundary coverage; full Auth tests pass in `e6e8e34`.
|
||||||
|
- Relocated the concrete PostgreSQL and Redis implementations from `repository/db/*` into `infrastructure/postgres` and `infrastructure/redis`, removed the temporary forwarding wrappers and empty unreferenced Mongo placeholder, and confirmed no runtime imports of the legacy implementation paths remain. Full tests, race tests, vet, and build pass in `1323aa4`; A003 is complete.
|
||||||
|
|
||||||
|
### `A004` — OTP application checkpoint
|
||||||
|
|
||||||
|
- Extracted OTP code generation and the default expiration into the transport-independent `application/otp` package while preserving the existing disabled-code and six-digit behavior; focused and full Auth tests pass in `0c92b14`.
|
||||||
|
- Extracted OTP template parameter decoding into the same application package and kept persistence JSON types at the infrastructure boundary; full Auth tests pass in `62fb1b1`.
|
||||||
|
- Extracted the three-attempt retry and already-used verification policy into `application/otp`; the gRPC use-case retains compatible status/error mapping and full tests pass in `133fcc3`.
|
||||||
|
- Added explicit OTP `Store` and `Sender` application contracts, isolating persistence and delivery concerns for the next adapter migration; full Auth tests pass in `8fbfcff`.
|
||||||
|
- Added concrete infrastructure adapters for the Redis OTP store and Kavenegar sender while preserving existing key/TTL behavior; full Auth tests pass in `cde73ef`.
|
||||||
|
- Wired the OTP adapters into runtime composition and generation, delivery, verification, and deletion paths while retaining compatibility fallback; full Auth tests pass in `c951875`.
|
||||||
|
- Wired the OTP template repository port and adapter into runtime composition and TFA processing; legacy fallback remains for compatibility and full Auth tests pass in `741415b`.
|
||||||
|
- Added thin Auth and internal Auth gRPC registration adapters and routed server registration through them; full Auth tests pass in `b56d54c`. A004 is complete; remaining legacy fallback removal is tracked under A008.
|
||||||
|
|
||||||
|
### `A005` — authentication/JWT checkpoint
|
||||||
|
|
||||||
|
- Extracted HTTP bearer-token normalization into `application/auth` and kept JWT verification/error mapping behavior unchanged; focused and full Auth tests pass in `1d72faa`.
|
||||||
|
- Extracted refresh-token marker validation into `application/auth` while preserving refresh-flow behavior; full Auth tests pass in `4225332`.
|
||||||
|
- Added access/refresh JWT verifier contracts and an infrastructure adapter delegating to the existing parser; full Auth tests pass in `ad6f5cc`. Runtime injection into all auth flows remains.
|
||||||
|
- Injected the verifier into IAM and refresh-token flows through runtime composition, retaining fallback for compatibility; full Auth tests pass in `6c5b8cc`.
|
||||||
|
- Extracted active/expiry session policy into `application/auth` with focused tests; integration into IAM/session retrieval remains for the next checkpoint (`424741c`).
|
||||||
|
- Added a domain-session `SessionStore` contract, infrastructure adapter over the legacy cache/persistence composition, and runtime wiring for IAM retrieval; full Auth tests pass in `d744ffc`. The adapter deliberately preserves existing Redis-expiry semantics without activating stricter status checks during the refactor.
|
||||||
|
- Routed login and refresh-session persistence through the same application boundary with legacy fallback retained; full Auth tests and vet pass in `c15bcff`.
|
||||||
|
- Added a distinct persistent `BySubject` session lookup and routed refresh-token rotation through it, deliberately keeping it separate from access-token Redis lookup so refresh validity is not capped by access expiry; full Auth tests and vet pass in `016d705`. A005 is complete; compatibility fallback removal remains under A008.
|
||||||
|
|
||||||
|
### `A006` — identity and permission checkpoint
|
||||||
|
|
||||||
|
- Extracted case-insensitive route/method evaluation and privileged-role detection into `application/permission`, retaining development-mode bypass and existing gRPC error mapping; focused and full Auth tests pass in `9f97cec`.
|
||||||
|
- Runtime-wired the permission repository adapter and routed permission initialization lookup/creation plus super-admin listing through the domain port, retaining legacy fallback; full Auth tests pass in `5b61adf`.
|
||||||
|
- Added an application role-permission reader and infrastructure adapter over the existing Redis/Postgres cache-aside path, then routed standard-user permission reads through it; full Auth tests pass in `24722cb`.
|
||||||
|
- Added an application identity store and infrastructure adapter over the existing identity cache/persistence composition, then routed identity reads/writes through pure domain mappings; full Auth tests pass in `113faef`.
|
||||||
|
- Extracted identity request normalization/validation into `application/identity`, preserving Persian-digit conversion and existing validation behavior while leaving protobuf mutation at the interface boundary; full Auth tests pass in `2d5ab3d`.
|
||||||
|
- Added identity ownership/person-verification application contracts and infrastructure adapters, runtime-wired both real and configured fake-provider paths, and preserved existing error mapping; full Auth tests and vet pass in `75c2e0d`. A006 is complete.
|
||||||
|
|
||||||
|
### `A007` — explicit Auth composition
|
||||||
|
|
||||||
|
- Replaced the eleven-argument positional constructor with a typed `Dependencies` graph assembled in `cmd/serve.go`, making OTP, JWT/session, permission, and identity infrastructure wiring explicit at bootstrap.
|
||||||
|
- The legacy two-argument constructor remains only as an A008 compatibility shim; full Auth tests and vet pass in `7d7871b`. A007 is complete.
|
||||||
|
|
||||||
|
### `A008` — Auth compatibility cleanup
|
||||||
|
|
||||||
|
- Removed the legacy two-argument constructor and all nil-dependent fallback implementations superseded by the explicit OTP, JWT/session, permission, and identity dependency graph.
|
||||||
|
- The remaining legacy repository methods are still active consumers for Auth operations outside the extracted paths and are therefore not dead/superseded code; full tests, race tests, and vet pass in `a9b11a3`. A008 and the Auth architecture phase are complete.
|
||||||
|
- A006 remains in progress: permission repository wiring and identity application orchestration still need extraction.
|
||||||
|
- A005 remains in progress: JWT validation, session checks, refresh-token flow, and broader authentication orchestration still need application ports and adapters.
|
||||||
|
|
||||||
### `I001` — publisher-backed ICO purchase map
|
### `I001` — publisher-backed ICO purchase map
|
||||||
|
|
||||||
- Compatibility entrypoints remain `WalletService.CalcBuyAsset` and `WalletService.BuyAsset`; API routes and existing request fields do not move.
|
- Compatibility entrypoints remain `WalletService.CalcBuyAsset` and `WalletService.BuyAsset`; API routes and existing request fields do not move.
|
||||||
@@ -220,3 +335,205 @@ Global config removal remains the separate follow-up `C002`.
|
|||||||
- `BuyAsset` delegates the pinned agreement to market. Market creates a taker/buy order owned by the buyer and calls the same synchronous `settleOrder` operation used by market matching.
|
- `BuyAsset` delegates the pinned agreement to market. Market creates a taker/buy order owned by the buyer and calls the same synchronous `settleOrder` operation used by market matching.
|
||||||
- Existing market confirmation keeps asynchronous behavior, while the ICO endpoint waits for settlement so `BuyAssetRes.success` reflects the actual result and hashes can be returned when available.
|
- Existing market confirmation keeps asynchronous behavior, while the ICO endpoint waits for settlement so `BuyAssetRes.success` reflects the actual result and hashes can be returned when available.
|
||||||
- Discounts are not applied to publisher orders: quote and settlement use the existing market-taker commission model, eliminating divergence between displayed and settled values.
|
- Discounts are not applied to publisher orders: quote and settlement use the existing market-taker commission model, eliminating divergence between displayed and settled values.
|
||||||
|
### `W001` — Wallet process and dependency migration map
|
||||||
|
|
||||||
|
All six runtime modes currently call `cmd/helper.SetupRepository*`, which constructs PostgreSQL, Redis, internal/external service clients, the GL/Kuknos availability gate, the GL outbox dispatcher, the global Stellar client, and optional profiling. `wallet`, `market`, `alert`, and `internal_wallet` use safe/lazy peer connection; `cron` and `stream` use strict peer connection. This shared bootstrap is a primary W003/W010/W011 separation point.
|
||||||
|
|
||||||
|
| Process / operation family | Current implementation | Persistence and cache | Queue / async | Internal and external dependencies | Stellar / availability |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| Wallet reads: health, assets/prices/commissions, networks, wallets/balances, transactions, BNPL, redeem/referral lists | `core/walletImp` (`health.go`, `asset.go`, `network.go`, `wallet.go`, `transaction.go`, `bnpl.go`, `redeem.go`, `commission.go`) | PostgreSQL Asset, Commission, Network, Wallet, Transaction, BNPL, Redeem, Federation, whitelist; repository cache helpers where invoked | None directly | Internal Authorization for identity/user data on selected operations | Availability gate for health; Stellar balance reads for synchronized wallet/balance operations |
|
||||||
|
| Wallet initialization and federation | `UserInitWallet`, `GetOrInitWallet`, `SyncUserWalletBalance`, `UserCreateFederation`, `UserGetFederation`, `GetPublicKeyByNationalID` | PostgreSQL TX, Wallet, Asset, Federation, Transaction, whitelist | GL ledger outbox may be enqueued in transactional paths | Internal Authorization; system encryption/key derivation | Recover/generate keys, activate accounts, create trustlines, query balances; Kuknos/GL gate at RPC boundary |
|
||||||
|
| Wallet transfers and locking | `InternalTransferAsset`, `ExternalTransferAsset`, `LockAsset`, release helpers, transaction tracking | PostgreSQL TX, Wallet, Transaction, LedgerOutbox | GL journals/events via transactional outbox | Authorization/InternalAuthorization for IAM/TFA/recipient resolution | Stellar balance, trustline checks, transfers, Horizon transaction tracking; availability interceptor |
|
||||||
|
| Asset buy and contracts | `CalcBuyAsset`, `BuyAsset`, `GenerateBuyContract`, `DeclineBuyContract`, discount helpers | PostgreSQL TX, Asset, Wallet, Transaction, Contract, Discount, buy whitelist (legacy Sale references remain in code) | GL/transaction event outbox through transaction paths | Market RPC; Authorization for agreement/IAM checks | Settlement delegates to wallet/market transfer paths; availability interceptor |
|
||||||
|
| IRT/IPG/accounting | `DepositIRT`, withdrawal init/confirm, `IPGGetToken`, `IPGConfirm`, `GetIPGLog` | PostgreSQL Accounting, WithdrawLog/IPGLog, Asset, Transaction, Wallet (legacy Sale references remain) | Notification calls are asynchronous at provider/RPC level; transaction/GL outboxes on financial paths | Authorization/InternalAuthorization, Notification, configured PSP (`Mellat`/`Vandar`), API gateway callback client | Stellar server/user transfers for IRT settlement; availability interceptor |
|
||||||
|
| Redeem, commission, referral and BNPL mutations | Redeem calculation/settlement, commission collect/refund/claim, BNPL submit/update/cancel/payment generation | PostgreSQL TX, Redeem, Asset, Wallet, Transaction, Commission, Discount, BNPL; Redis distributed mutex for commission claims | GL/transaction event outbox where financial transaction helpers are used | Authorization/InternalAuthorization as required | Stellar transfers for redeem/commission settlement; availability interceptor |
|
||||||
|
| Transaction-event pipeline (wallet process only) | `cmd/cmdServe/transaction_events.go`, `application/transactionevents` | PostgreSQL TransactionEventOutbox/Inbox/Deadbox and Transaction | Active RabbitMQ/Watermill publisher, subscriber, retry router, dispatcher; explicit startup/shutdown | Direct gRPC notifier to InternalAuthorization and Alert | Handler receives availability gate; financial event processing delegates to wallet service |
|
||||||
|
| Market reads and order lifecycle | `core/marketImp/market.go`: lists/details/history, calculate/new/cancel order | PostgreSQL Market, Asset, Commission, Contract, Transaction, TX; Redis mutex for order settlement | No active legacy market AMQP consumer (commented out) | Authorization/InternalAuthorization, Wallet/InternalWallet, Notification | Key generation and two-leg Stellar asset/IRT settlement with refund path; availability interceptor |
|
||||||
|
| ICO marketplace and market contracts | `core/marketImp/ico.go`, `contract.go`, `irt.go` | PostgreSQL Market, Contract, Asset | Uses wallet transaction/event mechanisms indirectly through internal RPCs | InternalAuthorization, Authorization, InternalWallet/Wallet | Settlement delegates to wallet and uses shared availability gate |
|
||||||
|
| Alert | `core/alertImp.Emit` | No domain persistence | Per-request goroutine; email retry group and parallel SMS | SMTP mail adapter and Kavenegar SMS adapter | No Stellar/availability interceptor |
|
||||||
|
| Internal-wallet RPC | Same `core/walletImp.walletSrv`, registered as `InternalWalletSrvServer` | Same PostgreSQL/Redis aggregates as invoked internal methods | Same GL/transaction outbox mechanisms | Primarily internal callers; Authorization/InternalAuthorization as operation requires | Same global Stellar client and availability interceptor |
|
||||||
|
| Cron | `core/cronJobs`: vacuum expired transactions and expire stale market orders, hourly at minute 1 with retry | PostgreSQL Transaction and Market | robfig cron scheduler; no RabbitMQ | Strict initialization currently connects all peers even though jobs only require persistence/config | Shared setup unnecessarily starts availability monitor, GL dispatcher, and Stellar client; W010 must narrow this |
|
||||||
|
| Stream | `port/stellar.StreamPayments` | Reads/writes through the full repository passed into streamer, including user/asset/transaction lookup paths | Horizon streaming callback loop; no RabbitMQ | Strict initialization currently connects all configured peers | Direct global Stellar/Horizon stream client; shared setup also starts availability/GL infrastructure |
|
||||||
|
|
||||||
|
Repository ownership map for migration:
|
||||||
|
|
||||||
|
- PostgreSQL adapters: Accounting/IPG/withdraw logs, Asset and buy/sell whitelists, Wallet, Federation, Transaction, TransactionEvent outbox/inbox/deadbox, LedgerOutbox, Discount, Commission, Contract/agreement, Redeem, BNPL, Network, Market, and transaction manager.
|
||||||
|
- Redis adapter: JSON cache primitives, key scan/delete, pub/sub (currently no active core consumer found), and distributed mutexes used by market and commission operations.
|
||||||
|
- Queue adapters: active RabbitMQ Watermill transaction-event bus plus PostgreSQL outbox/inbox/deadbox; the older market AMQP consumer is commented and must not be migrated as active behavior.
|
||||||
|
- Internal gRPC peers: Wallet, InternalWallet, Market, Authorization, InternalAuthorization, Notification, API gateway callback, and GL ledger/health clients.
|
||||||
|
- External adapters: SMTP, Kavenegar SMS, Mellat/Vandar PSP, Kuknos Horizon health, Horizon streaming, and Stellar account/trustline/balance/transfer operations.
|
||||||
|
- Cross-cutting bootstrap: configuration, logger/APM/Prometheus/reflection, system cryptography, profiling, availability gate, GL dispatcher, Stellar global initialization, and graceful shutdown.
|
||||||
|
|
||||||
|
Migration order implied by the map: isolate shared infrastructure constructors (W003), extract read-only wallet paths first (W004), then initialization/trustline (W005), financial transaction/event paths (W006), market/alert/internal RPCs (W007-W009), and finally give cron/stream minimal process-specific dependency graphs (W010) before the unified explicit composition cleanup (W011-W012).
|
||||||
|
|
||||||
|
### `W002` — Wallet domain foundation
|
||||||
|
|
||||||
|
- Added pure `domain/model` entities for Asset, Wallet, Federation, Network, Transaction, MarketOrder, Commission, Redeem, Accounting, and BNPL, using the existing exact fixed-point `money.Amount` value object rather than protobuf numeric fields.
|
||||||
|
- Added domain-owned status/side types, filters, AssetCode/TrackingCode normalization, wallet available-balance behavior, and focused tests.
|
||||||
|
- Added transport-independent domain errors and inward-facing repository, cache/lock, unit-of-work, blockchain, identity, notification, payment-gateway, and event-publisher ports.
|
||||||
|
- Verified the new packages contain no generated stub, GORM, repository, infrastructure, or database imports. Focused tests/vet and the full Wallet test suite pass in `ac649d2`; W002 is complete.
|
||||||
|
|
||||||
|
### `W003` — infrastructure adapter migration checkpoint
|
||||||
|
|
||||||
|
- Relocated every Wallet PostgreSQL repository implementation and its tests from `repository/db/postgres` to `infrastructure/postgres`, and every Redis implementation/test from `repository/db/redis` to `infrastructure/redis`.
|
||||||
|
- Updated `cmd/helper` to construct the infrastructure-owned adapters; no runtime import of the old PostgreSQL/Redis implementation paths remains. Full Wallet tests pass in `d2580cd`.
|
||||||
|
- RabbitMQ/Watermill was already under `infrastructure/eventbus`; external service clients now live under `infrastructure/service` (Darano, Kavenegar, Mellat, and Vandar), and Stellar/Horizon operations now live under `infrastructure/stellar`.
|
||||||
|
- Wallet, market, stream, and bootstrap call sites no longer import legacy implementation paths under `repository/db`, `repository/service`, or `port/stellar`. Temporary/non-Go artifacts left under the old service directory are not runtime implementations.
|
||||||
|
- Full Wallet tests, race tests, vet, and build pass after the migration (`d121fc9`); W003 is complete.
|
||||||
|
|
||||||
|
### `W004` — read-only wallet application boundary checkpoint
|
||||||
|
|
||||||
|
- Added `application/walletread`, with transport-independent catalog, commission, network, and balance reader ports and use-case methods.
|
||||||
|
- gRPC methods for asset list/get, asset commissions, asset price, network list, health, balance, and check-balance now delegate through the application boundary; protobuf conversion and existing error mapping remain in `core/walletImp`.
|
||||||
|
- Transaction-list querying and blockchain balance reads now delegate through the application reader as well. Wallet listing consumes the application catalog; its database synchronization remains an explicit mutation in the service and is deferred to later wallet work. Full Wallet tests pass in `5b17c82`; W004 is complete.
|
||||||
|
|
||||||
|
### `W005` — wallet initialization boundary checkpoint
|
||||||
|
|
||||||
|
- Added `application/walletinit` for the identity precondition and exact Stellar trustline-limit policy.
|
||||||
|
- `UserInitWallet` delegates those rules and the key-recovery/trustline adapter while retaining the existing database transaction, wallet creation, transaction recording, and rollback behavior.
|
||||||
|
- Wallet-code generation is also application-owned and tested. Full Wallet tests pass in `c09fdf8`; orchestration extraction remains in progress.
|
||||||
|
- Wallet draft construction (user, asset, federation, code, and timestamps) is application-owned and tested; repository lookup/insertion remains at the service boundary. Full Wallet tests pass in `28d0846`; orchestration extraction remains in progress.
|
||||||
|
- Repository-backed wallet/federation find-or-create orchestration is now application-owned with injected repositories and federation creation callback; `UserInitWallet` delegates it while retaining transaction scope. Full Wallet tests pass in `63d4d52`; transaction recording and rollback policy extraction remains.
|
||||||
|
- Trustline transaction construction is now application-owned and tested; the service still performs the insert and rollback decisions at the transaction boundary. Full Wallet tests pass in `1999ec0`; rollback policy extraction remains.
|
||||||
|
- `UserInitWallet` now uses named-return transaction finalization: successful execution commits, while any returned error rolls back (including failures after key recovery or trustline submission). Full Wallet tests pass in `4e4f2af`; broader integration coverage remains before W005 completion.
|
||||||
|
- Commit-on-success and rollback-on-error behavior is covered by focused application tests in addition to the service wiring. Full Wallet tests pass in `3bc9591`; broader integration coverage remains before W005 completion.
|
||||||
|
- Existing-wallet and federation-create wallet paths are covered with repository fakes, alongside transaction finalization tests. Full Wallet tests pass in `15200dc`; broader integration coverage remains before W005 completion.
|
||||||
|
|
||||||
|
### Federation removal investigation (`A009` / `W013`)
|
||||||
|
|
||||||
|
- Federation is not currently safe to delete outright: wallet persistence links `wallet.federation_id`, transaction records expose nullable `from_federation_id`/`to_federation_id`, generated wallet APIs expose federation messages, and wallet code still has federation lookup/creation paths.
|
||||||
|
- Auth has no active federation implementation; its wallet federation client is commented/dead code. Auth’s identity service should remain the owner of identity and national-ID data.
|
||||||
|
- The proposed target is reasonable only after consumers are migrated: `user_id → identity_id → wallet_id`, with `wallet_id` still scoped to `asset_id` and Stellar key derivation/custody explicitly preserved. W013 must first identify whether federation addresses or transaction routing are actually supported in production, then remove or retain the model based on evidence and a data/API compatibility plan.
|
||||||
|
- Per the requested migration, federation is fully removed from active Wallet/Auth/API code and the shared wallet protobuf: no federation creation/lookup, persistence adapter/model, wallet field, transaction field/filter, generated message, stale API route, or runtime reference remains. New wallet creation uses user/asset identity; wallet records remain asset-scoped. Wallet/Auth/API contracts were regenerated and all service tests pass. The database must be migrated separately to drop legacy federation columns/tables in deployed environments.
|
||||||
|
|
||||||
|
### `W006` — deposit/withdrawal/transaction boundary checkpoint
|
||||||
|
|
||||||
|
- Added `application/withdrawal` with the IRT amount reconciliation policy and focused tests for the one-unit balance threshold.
|
||||||
|
- `WithdrawIRTInit` continues to own the gRPC/payment flow but delegates amount policy through the application package; full Wallet tests pass in `16ebd2d`.
|
||||||
|
- IPG Toman/Rial conversion, positivity, rounding, and exactness checks now live in `application/deposit`; the gRPC/payment flow delegates through wrappers and remains response-compatible. Full Wallet tests pass in `a565ce0`.
|
||||||
|
- Transfer display-to-raw amount conversion and positive/exactness validation now live in `application/transfer`; the gRPC service retains protocol-specific error mapping. Full Wallet tests pass in `1e5b977`.
|
||||||
|
- Settled IPG deposits now use `application/deposit.RawSettlementAmount` for Rial→Toman→raw conversion, retaining exactness checks before Stellar transfer. Full Wallet tests pass in `08c2d7b`.
|
||||||
|
- Transaction status-update construction now lives in `application/transaction`; Stellar polling remains at the infrastructure-facing service while persistence update shape is application-owned. Full Wallet tests pass in `7941966`.
|
||||||
|
- Transaction-event type support is centralized in `application/transactionevents`, removing the duplicate wallet-server policy. Full Wallet tests pass in `4d03adb`.
|
||||||
|
- IPG payer-ID derivation is now application-owned with short/invalid input protection and deterministic tests; the gRPC service delegates through a compatibility wrapper. Full Wallet tests pass in `f12752d`.
|
||||||
|
- Pending IRT deposit and withdrawal transaction-record construction is now application-owned and tested; persistence insertion remains at the gRPC/service boundary. Full Wallet tests pass in `0efc199`.
|
||||||
|
- Pending internal and external transfer transaction-record construction is now application-owned and tested; repository insertion and transfer execution remain at the gRPC/service boundary. Full Wallet tests pass in `98753f7`.
|
||||||
|
- The active IRT deposit creation path now also uses the shared `application/transaction.PendingDeposit` policy; repository insertion and IPG orchestration remain at the service boundary. Focused Wallet tests pass in `b009837`.
|
||||||
|
- Successful commission and referral-commission transaction records now use the shared `application/transaction.SuccessfulTransfer` policy; Stellar execution and repository insertion remain at the service boundary. Full Wallet tests pass in `a4717d9`.
|
||||||
|
- IPG settlement success updates now use the shared `application/transaction.SettlementUpdate` policy for hash, status, and settled amount; repository update and external transfer remain at the service boundary. Focused Wallet tests pass in `f9b3c46`.
|
||||||
|
- IRT dev-mode completion updates now use the shared `application/transaction.HashStatusUpdate` policy; insert-vs-update branching and repository persistence remain at the service boundary. Focused Wallet tests pass in `926ea23`.
|
||||||
|
- IRT dev-mode successful-deposit creation now uses the shared `application/transaction.SuccessfulDeposit` policy; insert error handling and completion orchestration remain at the service boundary. Focused Wallet tests pass in `89027b4`.
|
||||||
|
- Redeem transaction creation now uses the shared `application/transaction.PendingRedeem` policy; repository insertion and Stellar transfer orchestration remain at the service boundary. Focused Wallet tests pass in `e8fa40d`.
|
||||||
|
- Redeem completion status/hash/error updates now use the shared `application/transaction.CompletionUpdate` policy; repository update and transfer error orchestration remain at the service boundary. Focused Wallet tests pass in `af880c5`.
|
||||||
|
- Transaction-list balance-change classification now uses the shared `application/transaction.BalanceChange` policy with focused coverage for increases, decreases, and non-balance transaction types. Full Wallet tests pass in `ca7ae43`.
|
||||||
|
- Internal transfer and sell insufficient-balance transitions now use the shared `application/transaction.FailureUpdate` policy; atomic wallet/transaction persistence and rollback behavior remain unchanged. Focused Wallet tests pass in `d10ff42`.
|
||||||
|
- Internal transaction consumers now acquire distinct sender/recipient wallet locks through deterministic `application/transaction.LockUserIDs` ordering, preventing reverse-transfer lock-order deadlocks. Focused Wallet tests pass in `a43a758`.
|
||||||
|
- Transaction persistence atomically enqueues ledger and transaction-event outbox records; deterministic idempotency keys, duplicate/conflict handling, retry claims, and dead-letter behavior are implemented and covered by infrastructure/application tests. Remaining W006 work is balance coordination and business-level failure/refund orchestration in deposit, withdrawal, transfer, and redeem flows.
|
||||||
|
|
||||||
|
### `W007` — market boundary checkpoint
|
||||||
|
|
||||||
|
- ICO agreement amount tolerance is now application-owned in `application/market.AgreementAmountMatches`, using the existing fixed-point money type and preserving the 0.5-unit tolerance. The market gRPC package delegates through a compatibility wrapper; focused market tests pass in `3d9e1af`.
|
||||||
|
- Pricing, order lifecycle, settlement, contract generation, and external adapter composition remain for subsequent W007 increments.
|
||||||
|
- ICO available-amount validation now uses `application/market.ValidateAvailableAmount` with application-level sentinel errors mapped to existing gRPC error codes by the market adapter. Focused market tests pass in `bbb3443`.
|
||||||
|
- Market display-to-raw amount conversion now uses `application/market.RawAmount`, preserving exact fixed-point conversion and positive-amount checks. Focused market tests pass in `d217623`.
|
||||||
|
- Market pricing arithmetic now uses typed `application/market.CalculationInput`/`CalculationResult`; the gRPC adapter maps commission persistence values and protobuf fields at the boundary. Existing maker/taker and base/asset side behavior is covered by focused market tests in `e21ecf2`.
|
||||||
|
- Market order amount and maker unit-price positivity checks now use `application/market.PositiveAmount`, with existing zero-amount gRPC mapping retained. Focused market tests pass in `192dff4`.
|
||||||
|
- Market order status-to-error-code policy now uses `application/market.OrderStatusCode`; the adapter retains existing `allowed` metadata formatting. Focused market tests pass in `9f70b21`.
|
||||||
|
- ICO publisher role/participant/side/counter-asset validation now uses `application/market.ValidatePublisherICO`, with existing access-denied and invalid-argument mappings retained. Focused market tests pass in `4ea1f5a`.
|
||||||
|
- Market settlement now synchronously acquires the stream transaction-hash mutex; the previous goroutine lock returned immediately and did not serialize settlement against stream processing. Focused market tests pass in `3004bb9`.
|
||||||
|
|
||||||
|
### `W008` — alert boundary checkpoint
|
||||||
|
|
||||||
|
- Alert level and source presentation labels now use `application/alert.LevelLabel` and `SourceLabel`; asynchronous email/SMS delivery, five-retry behavior, and error propagation remain at the alert adapter. Focused Wallet tests pass in `085cb25`.
|
||||||
|
- Alert subject formatting now uses `application/alert.Subject`, preserving timestamp and localized level/source labels while delivery remains adapter-owned. Focused Wallet tests pass in `be29c11`.
|
||||||
|
- Alert `Emit` now rejects nil events synchronously instead of panicking in its delivery goroutine; valid event delivery behavior is unchanged. Focused alert tests pass in `4fc4726`.
|
||||||
|
- Alert `Emit` now also rejects events without IAM/user data before starting the delivery goroutine, preventing nil dereferences. Focused alert tests pass in `b3e1dbc`.
|
||||||
|
|
||||||
|
### `W010` — cron/stream bootstrap checkpoint
|
||||||
|
|
||||||
|
- Cron retry behavior now uses `application/cron.Retry`; scheduler registration, skip/recover middleware, and job dependencies remain in `core/cronJobs`. Focused Wallet tests pass in `8e27342`.
|
||||||
|
- Stellar payment stream lookup classification now uses `application/stream.IsNew`, preserving not-found and invalid empty-result behavior while keeping Horizon/database access in infrastructure. Focused Wallet tests pass in `6c3243c`.
|
||||||
|
- Cron command now uses `SetupCronRepository`, avoiding unnecessary strict service peers, availability monitor, Stellar client, profiling server, and ledger dispatcher initialization; cron jobs receive only PostgreSQL-backed repository dependencies. Focused command tests pass in `08f3225`.
|
||||||
|
- Stellar stream external-deposit transaction construction now uses `application/transaction.SuccessfulExternalDeposit`; network parsing, deduplication, locking, and repository insertion remain infrastructure-owned. Focused stream/transaction tests pass in `61768e7`.
|
||||||
|
- Stream command now uses a dedicated setup path that retains required service/Redis/availability/Stellar dependencies while skipping the ledger dispatcher and profiling server; shared repository setup is option-driven for later process composition. Command tests pass in `db52f89`.
|
||||||
|
|
||||||
|
### `W009` — internal-wallet boundary checkpoint
|
||||||
|
|
||||||
|
- Lock/release balance mutation policy now uses `application/walletlock.Lock` and `Release`, preserving available/frozen balance rules while keeping transaction scope, ledger journal creation, persistence, and gRPC error mapping in `core/walletImp`. Focused Wallet tests pass in `382fd79`.
|
||||||
|
|
||||||
|
### `W011` — explicit process composition checkpoint
|
||||||
|
|
||||||
|
- Alert command now uses `SetupAlertRepository`, which initializes only lazy service clients required for mail/SMS delivery and no longer starts PostgreSQL, Redis, availability, Stellar, ledger-dispatch, or profiling infrastructure. Command tests pass in `da074f9`.
|
||||||
|
- Market command now uses `SetupMarketRepository`, retaining PostgreSQL/Redis/services/availability/Stellar while skipping ledger-dispatch and profiling startup. Command and market tests pass in `0132734`.
|
||||||
|
- Internal-wallet command now uses `SetupInternalWalletRepository`, retaining PostgreSQL/Redis/services/Stellar while skipping availability, ledger-dispatch, and profiling startup. Command and wallet tests pass in `f46df4c`.
|
||||||
|
- Main wallet command now uses the explicit `SetupWalletRepository` entry point for its full dependency profile, completing named setup entry points for all five service modes. Command and wallet tests pass in `cf13a58`.
|
||||||
|
|
||||||
|
### `W012` — superseded implementation cleanup checkpoint
|
||||||
|
|
||||||
|
- Removed the now-redundant `core/marketImp/amount.go` shim and routed market settlement directly to `application/market.RawAmount`; focused market tests pass in `085140c`.
|
||||||
|
- Removed the redundant `agreementAmountMatches` wrapper and routed ICO agreement checks/tests directly to `application/market.AgreementAmountMatches`; focused market tests pass in `261c6a1`.
|
||||||
|
- Removed the redundant `core/walletImp/ipg_amount.go` shim and routed IPG Toman/Rial conversion callers/tests directly to `application/deposit`; focused Wallet tests pass in `1493486`.
|
||||||
|
- Removed the redundant `nationalIdToPayerID` wrapper and routed IPG payer-ID generation directly to `application/deposit.PayerID`; focused Wallet tests pass in `c710cdc`.
|
||||||
|
- Discount amount calculation (percentage + static amount with max cap) now uses `application/discount.CalculateAmount`; wallet callers/tests route directly to the application policy. Focused Wallet tests pass in `ccff76e`.
|
||||||
|
- Referral commission splitting and claimed/unclaimed aggregation now use `application/referral`; the old `core/walletImp` arithmetic implementation was removed and callers/tests route directly to application policies. Focused Wallet tests pass in `37612bf`.
|
||||||
|
- Redeem lot reconstruction, FIFO allocation, and ceiling-day profit calculation now use `application/redeem`; the old core implementation and internal result types were removed, with service/tests adapted to exported application allocations. Focused Wallet tests pass in `bd8d07d`.
|
||||||
|
- Contract percentage rounding now uses `application/contract.RoundTo`; duplicate wallet/market helpers were removed. Focused contract, wallet, and market tests pass in `ab4091e`.
|
||||||
|
- Agreement identifier derivation now uses the deterministic `application/contract.AgreementID` policy for both ICO and market contracts; duplicate service implementations were removed. Focused contract, wallet, and market tests pass in `dc0bdf4`.
|
||||||
|
|
||||||
|
### `W005` initialization checkpoint
|
||||||
|
|
||||||
|
- Wallet initialization now propagates transaction commit failures through the application `FinalizeTransaction` policy instead of silently discarding them; focused wallet-init and wallet service tests pass in `f9a0262`.
|
||||||
|
|
||||||
|
### `W006` transaction boundary checkpoint
|
||||||
|
|
||||||
|
- Internal transaction event processing now rejects nil/invalid event IDs before repository access and explicitly rolls back when an unsupported transaction type is received; focused wallet transaction tests pass in `66d271e`.
|
||||||
|
|
||||||
|
### `W009` internal-wallet boundary checkpoint
|
||||||
|
|
||||||
|
- Lock and release RPC handlers now reject nil or incomplete IAM requests before dereferencing user fields; focused wallet lock tests pass in `36b4d67`.
|
||||||
|
- Successful lock and release operations now return an explicit `StatusRes{Success:true}` instead of a nil response; focused wallet lock tests pass in `0920702`.
|
||||||
|
|
||||||
|
### `W010` cron boundary checkpoint
|
||||||
|
|
||||||
|
- Cron retry execution now emits error telemetry only when a job ultimately fails, avoiding nil error logs on successful runs; focused cron tests pass in `ba14ce1`.
|
||||||
|
- Cron registration now reads a configurable `Cron.Schedule` value, retaining `1 * * * *` as the default; config and cron tests pass in `5f37e56`.
|
||||||
|
|
||||||
|
## Wallet phase completion — `W005`–`W012` (2026-08-31)
|
||||||
|
|
||||||
|
- `W005`: wallet initialization now delegates identity prerequisites, key recovery/generation, wallet creation, trustline submission, and trustline transaction construction through `application/walletinit`. The trustline transaction is inserted inside the same database transaction, and `application/unitofwork` provides checked commit/rollback finalization.
|
||||||
|
- `W006`: deposit, withdrawal, transfer, transaction construction/status, deterministic account locking, and balance coordination live in application packages. `application/transaction.Processor` owns buy/sell/redeem/transfer wallet mutation and transaction completion. Transaction/ledger outbox idempotency remains atomic. Failures after PSP settlement mark the linked transaction failed; the active Vandar provider contract exposes no reversal endpoint, so the implementation does not invent one.
|
||||||
|
- `W007`: `application/market` owns pricing, validation, maker/taker construction, capacity checks, settlement transitions, and cancellation balance-release policy. Settlement is synchronous, checked, and persists failure status instead of returning optimistic success.
|
||||||
|
- `W008`: `application/alert.DeliveryService` owns context-aware email retry and SMS delivery behind ports; the gRPC adapter validates and dispatches asynchronously without business-delivery duplication.
|
||||||
|
- `W009`: `application/walletlock` owns load/mutate/save/journal orchestration through injected ports. The gRPC adapter owns database transaction scope and maps domain errors to protocol errors.
|
||||||
|
- `W010`: cron and stream have dedicated composition. `application/stream.Service` owns payment availability checks, internal/external filtering, amount parsing, idempotency, locking, and external-deposit transaction creation. Duplicate cron command registration was removed.
|
||||||
|
- `W011`: all six runtime modes use explicit dependency profiles; superseded generic strict/safe repository setup entry points and option names are removed.
|
||||||
|
- `W012`: gRPC adapters moved from `core/*Imp` to `interface/grpc`, cron moved to `interface/process/cron`, legacy `*Imp` package names were removed, and superseded helpers/shims were deleted. No live code references the old core packages or generic setup entry points.
|
||||||
|
- Final Wallet commit is `240b8d0` on `feat/refactor-v1`. Protobuf regeneration produced no diff; full tests, race tests, vet, build, and whitespace checks all pass.
|
||||||
|
|
||||||
|
## API phase completion — `G001`–`G008` (2026-08-31)
|
||||||
|
|
||||||
|
- `G001`: API `ARCHITECTURE-COMPATIBILITY.md` records all 57 active `/v1` method/path contracts, four auxiliary endpoints, optional static serving, middleware order, success/error envelopes, header-to-gRPC metadata behavior, Swagger selection, pprof, WebSocket messages, and peer lifecycle expectations.
|
||||||
|
- `G002`: `application/port.Upstreams` is the transport-facing boundary and `infrastructure/grpcclient` owns generated clients. Connections are created on first RPC, connection creation is serialized, active calls prevent idle closure, the configured inactivity timeout defaults to two minutes, idle peers close, later calls reconnect, health failures remain request-tolerant, and process shutdown explicitly closes all peers. Focused tests cover no eager dial, reuse, idle close/reconnect, and invalid composition.
|
||||||
|
- `G003`: middleware moved to `interface/http/middleware`. `Chain` makes the compatibility-critical APM → profiling → Prometheus → CORS → JSON → i18n → error → optional logger order explicit and tested. The legacy profiling adapter's missing `c.Next()` path was corrected so non-verbose deployments serve requests.
|
||||||
|
- `G004`/`G005`: all public and authenticated handlers, binder, response helpers, middleware-facing IAM logic, and route registration moved to `interface/http/handler`. A complete route-matrix test asserts every versioned method/path; existing authorization, metadata, protobuf binding, status/error translation, and response envelopes are retained.
|
||||||
|
- `G006`: `interface/http` now owns the Gin router, readiness, metrics, Swagger, WebSocket, main HTTP server, separate pprof server, timeouts, and graceful shutdown. Tests cover auxiliary route registration, environment-specific Swagger URLs, and WebSocket wire-message formatting.
|
||||||
|
- `G007`: `cmd/apiRuntime` is the explicit dependency graph for upstream clients, HTTP handlers, router, server ownership, startup permission synchronization, and shutdown. Construction is side-effect-free and its complete 61-route graph is tested.
|
||||||
|
- `G008`: removed root `service`, `handler`, and `middlewares` packages; the generated service enum/reflection lookup, unused mock-data helper, empty error-enum shell, commented legacy handlers/routes, and `gofakeit` dependency are gone. No legacy package import or duplicate client/handler implementation remains.
|
||||||
|
- Final API commit is `31e3043` on `feat/refactor-v1`. `make build-proto` and writable-cache `make build-swag` reproduce committed outputs with no diff; `go test ./...`, `go test -race ./...`, `go vet ./...`, `go build ./...`, and whitespace checks pass.
|
||||||
|
|
||||||
|
## AdminPanel/protobuf phase completion — `P001`–`P010`, `R001`–`R003` (2026-08-31)
|
||||||
|
|
||||||
|
- `AdminPanel/ADMIN-MUTATION-INVENTORY.md` is the evidence baseline. Asset administration was the only sufficiently specified missing service contract; generic wallet, transaction, market, auth, or configuration CRUD was rejected because it would bypass aggregate invariants.
|
||||||
|
- Proto adds only typed, additive `AdminUpsertAsset` and `AdminDeactivateAsset` commands. Wallet authenticates them using fail-closed `x-admin-token` metadata and configurable token state.
|
||||||
|
- `application/adminasset` owns activation constraints, decimal and buy-limit validation, metadata defaults, token-type derivation, persistence, cache invalidation, and safe deactivation. Custody fields absent from the legacy Django projection are preserved on update.
|
||||||
|
- AdminPanel generates its active BetterProto message subset from the adjacent local proto checkout. Its wallet adapter applies configurable address, timeout, and credential metadata and translates permission, validation, timeout, transport, and status failures.
|
||||||
|
- Unmanaged Django models are read-only by default. Assets are the sole explicit service-backed exception; asset prices, inlines, imports, bulk deletion, legacy persistence signals, and all other direct mutation paths are disabled.
|
||||||
|
- Router typo and tests are complete. Buf lint/build/breaking checks pass; full Wallet tests pass; thirteen AdminPanel boundary tests, Django checks, compilation, regeneration, and whitespace checks pass.
|
||||||
|
|
||||||
|
## Final phase completion — `F001`–`F005` (2026-09-01)
|
||||||
|
|
||||||
|
- Cross-context evaluation rejected a universal ID or monetary source package: Wallet and GL precision/arithmetic invariants differ, while deployed identifier families have distinct ownership, signedness, namespace, and opacity. The evidence and approved conversion rules are in `SHARED-TYPES-EVALUATION.md`.
|
||||||
|
- Final regeneration corrected previously missing API/Auth Wallet admin-contract consumers (`0074e91`, `2c8a0b1`). Required JSON-tag behavior remains governed by each consumer's established generator workflow.
|
||||||
|
- Wallet's full race gate exposed a test synchronization window: the duplicate was published after notification but before the first inbox success transition. Commit `3b898e1` waits for the actual success transition; 20 focused race repetitions and the complete race suite pass.
|
||||||
|
- Every active Go repository passes generation, normal tests, race tests, vet, and native build. Proto passes lint/build/breaking. AdminPanel passes local generation, thirteen focused tests, Django checks, compilation, and whitespace checks.
|
||||||
|
- API/Auth/Wallet/GL/AdminPanel/Proto are clean on `feat/refactor-v1`; final results and deployment requirements are consolidated in `FINAL-MIGRATION-REPORT.md`.
|
||||||
|
|||||||
+137
-51
@@ -42,9 +42,9 @@ This is the authoritative execution tracker for the refactor. Work is performed
|
|||||||
| C001 | `DONE` | Refactor `auth` config loading into `infrastructure/config`. | Koanf loader/facade tests, race tests, generation, full tests, and build pass; committed as `29b7e07`. |
|
| C001 | `DONE` | Refactor `auth` config loading into `infrastructure/config`. | Koanf loader/facade tests, race tests, generation, full tests, and build pass; committed as `29b7e07`. |
|
||||||
| C002 | `DONE` | Replace `auth` global config reads with constructor injection. | No global/legacy reads remain; tests, race tests, generation, tidy, and build pass; committed as `1bd5559`. |
|
| C002 | `DONE` | Replace `auth` global config reads with constructor injection. | No global/legacy reads remain; tests, race tests, generation, tidy, and build pass; committed as `1bd5559`. |
|
||||||
| C003 | `DONE` | Refactor `wallet` config loading into `infrastructure/config`. | Fig defaults and all five configs verified; tests/race/build pass; committed as `7958530`. |
|
| C003 | `DONE` | Refactor `wallet` config loading into `infrastructure/config`. | Fig defaults and all five configs verified; tests/race/build pass; committed as `7958530`. |
|
||||||
| C004 | `CHANGED` | Replace `wallet` global config reads with constructor injection. | Priority changed by the GL requirement after dependency inventory; resume as a new tracked task after the ledger adapter boundary stabilizes. |
|
| C004 | `DONE` | Replace `wallet` global config reads with constructor injection. | Config is injected through commands, services, repositories, use cases, adapters, cron, logger, and Stellar; the legacy facade is removed; full tests/race/vet/build pass; completed in the series ending at `4d192a6`. |
|
||||||
| C005 | `TODO` | Move `api` config loading into `infrastructure/config`. | Koanf behavior and baked-in defaults remain compatible. |
|
| C005 | `DONE` | Move `api` config loading into `infrastructure/config`. | Pure koanf/TOML loading and baked-in defaults are preserved under `infrastructure/config`; loader tests pass; completed in `44d56d3`. |
|
||||||
| C006 | `TODO` | Replace `api` global config reads with constructor injection. | Server, middleware, Swagger, profiling, and clients receive explicit config. |
|
| C006 | `DONE` | Replace `api` global config reads with constructor injection. | Command, logger, middleware, handlers, services, Swagger, profiling, and clients receive explicit config; no legacy global reads/imports remain; tests/race/vet/build pass; completed in `44d56d3`. |
|
||||||
|
|
||||||
## Priority workstream — General Ledger (`GL`)
|
## Priority workstream — General Ledger (`GL`)
|
||||||
|
|
||||||
@@ -58,8 +58,8 @@ This is the authoritative execution tracker for the refactor. Work is performed
|
|||||||
| L006 | `DONE` | Add a wallet-owned ledger port and GL gRPC adapter. | Wallet owns transport-neutral journal/event types; adapter maps them to generated GL messages with deadlines/TLS options and tests; committed as `9d91f8f`. |
|
| L006 | `DONE` | Add a wallet-owned ledger port and GL gRPC adapter. | Wallet owns transport-neutral journal/event types; adapter maps them to generated GL messages with deadlines/TLS options and tests; committed as `9d91f8f`. |
|
||||||
| L007 | `DONE` | Add a durable wallet outbox for ledger delivery. | Transactional enqueue, locked claiming, stale recovery, retry/backoff, quarantine/replay, dispatcher, and commit/rollback tests pass; committed as `379dbc2`. |
|
| L007 | `DONE` | Add a durable wallet outbox for ledger delivery. | Transactional enqueue, locked claiming, stale recovery, retry/backoff, quarantine/replay, dispatcher, and commit/rollback tests pass; committed as `379dbc2`. |
|
||||||
| L008 | `CHANGED` | Integrate ledger recording into every wallet transaction path. | Scope split after implementation: all Wallet-owned deposit, withdrawal, transfer, buy, redeem, commission, market, IPG, stream, lock/release, and lifecycle paths are mapped and dispatched (`ff31c87`, `d1aa339`); AdminPanel direct writes remain under `P006`/`P008`. |
|
| L008 | `CHANGED` | Integrate ledger recording into every wallet transaction path. | Scope split after implementation: all Wallet-owned deposit, withdrawal, transfer, buy, redeem, commission, market, IPG, stream, lock/release, and lifecycle paths are mapped and dispatched (`ff31c87`, `d1aa339`); AdminPanel direct writes remain under `P006`/`P008`. |
|
||||||
| L009 | `TODO` | Implement reconciliation and disaster-read tooling. | Missing/duplicate/mismatched blockchain records are detectable; ledger can reconstruct account/asset balances deterministically. |
|
| L009 | `DONE` | Implement reconciliation and disaster-read tooling. | Read-only journal integrity scans, external settlement evidence comparison, duplicate detection, account/balance reconstruction, and explorer reads are implemented and tested; commits `3f5fd86`, `b14c5e2`, and `d5c9b33`. |
|
||||||
| L010 | `TODO` | Run outage, replay, ordering, concurrency, and recovery verification. | No committed wallet transaction is lost; duplicates do not double-post; unbalanced journals never commit. |
|
| L010 | `DONE` | Run outage, replay, ordering, concurrency, and recovery verification. | Replay/idempotency, rollback, ordering, conservation, concurrent load scenarios, and recovery behavior are covered by GL tests/load tests; full tests/race/vet/build pass. |
|
||||||
|
|
||||||
## Priority workstream — Publisher-backed ICO purchases
|
## Priority workstream — Publisher-backed ICO purchases
|
||||||
|
|
||||||
@@ -104,77 +104,79 @@ This is the authoritative execution tracker for the refactor. Work is performed
|
|||||||
|
|
||||||
| ID | Status | Task | Acceptance check / note |
|
| ID | Status | Task | Acceptance check / note |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| A001 | `TODO` | Map every auth RPC to business operations and dependencies. | Method-level migration map exists before package moves. |
|
| A001 | `DONE` | Map every auth RPC to business operations and dependencies. | Method-level migration map is recorded in `REFACTORING-AUDIT.md`; completed on `2026-08-30`. |
|
||||||
| A002 | `TODO` | Introduce auth domain entities, value objects, errors, and repository ports. | Domain packages contain no gRPC, GORM, Redis, or framework imports. |
|
| A002 | `DONE` | Introduce auth domain entities, value objects, errors, and repository ports. | Added pure Auth entities/value objects, domain errors, and inward-facing repository/cache ports with no gRPC, GORM, Redis, or framework imports; committed as `32f182b`/`d292822`. |
|
||||||
| A003 | `TODO` | Move auth persistence and Redis implementations into infrastructure. | Explicit persistence/domain mappings exist and repository tests pass. |
|
| A003 | `DONE` | Move auth persistence and Redis implementations into infrastructure. | PostgreSQL and Redis implementations now live directly under `infrastructure`; legacy implementation packages and the unused Mongo placeholder are removed; full tests/race/vet/build pass. |
|
||||||
| A004 | `TODO` | Extract OTP application use cases and thin gRPC adapters. | OTP behavior and status mapping remain compatible. |
|
| A004 | `DONE` | Extract OTP application use cases and thin gRPC adapters. | OTP primitives, persistence/provider adapters, runtime/template wiring, and thin gRPC registration adapters are in place; full Auth tests pass. |
|
||||||
| A005 | `TODO` | Extract authentication/JWT application use cases and adapters. | Token behavior, validation, and status mapping remain compatible. |
|
| A005 | `DONE` | Extract authentication/JWT application use cases and adapters. | Token policies, JWT verification, cached/persistent session reads, and session writes are extracted and runtime-wired while preserving access/refresh expiry semantics. |
|
||||||
| A006 | `TODO` | Extract identity and permission use cases and adapters. | Public and internal authorization services pass tests. |
|
| A006 | `DONE` | Extract identity and permission use cases and adapters. | Permission policy/read paths and identity storage, validation, and external verification boundaries are extracted/runtime-wired; full tests and vet pass. |
|
||||||
| A007 | `TODO` | Replace auth bootstrap with explicit dependency composition. | Dependency direction is enforced and the service builds. |
|
| A007 | `DONE` | Replace auth bootstrap with explicit dependency composition. | Auth bootstrap constructs a typed dependency graph for OTP, JWT/session, permission, and identity boundaries; full tests and vet pass. |
|
||||||
| A008 | `TODO` | Remove superseded auth packages and compatibility shims. | No dead imports or duplicate implementations remain. |
|
| A008 | `DONE` | Remove superseded auth packages and compatibility shims. | Removed the legacy constructor and all runtime nil/fallback branches superseded by explicit OTP, JWT/session, permission, and identity dependencies; full tests/race/vet pass. |
|
||||||
|
| A009 | `DONE` | Audit and remove auth-side federation coupling. | Confirmed federation has no live Auth responsibility and removed the commented/dead wallet federation client; identity remains the owner of identity and national-ID data. |
|
||||||
|
|
||||||
## Phase 3 — `wallet` architecture
|
## Phase 3 — `wallet` architecture
|
||||||
|
|
||||||
| ID | Status | Task | Acceptance check / note |
|
| ID | Status | Task | Acceptance check / note |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| W001 | `TODO` | Map wallet, market, alert, internal-wallet, cron, stream, DB, Redis, queue, and Stellar dependencies. | Method/process-level migration map exists. |
|
| W001 | `DONE` | Map wallet, market, alert, internal-wallet, cron, stream, DB, Redis, queue, and Stellar dependencies. | Process/operation-family map, repository ownership, active queue topology, peer/provider dependencies, Stellar coupling, and migration order are recorded in `REFACTORING-AUDIT.md`. |
|
||||||
| W002 | `TODO` | Introduce wallet domain entities, value objects, errors, and repository ports. | Domain packages have no transport or infrastructure dependencies. |
|
| W002 | `DONE` | Introduce wallet domain entities, value objects, errors, and repository ports. | Added transport/persistence-independent wallet entities, filters, value objects, domain errors, repositories, cache/UoW, blockchain, identity, notification, PSP, and event ports; focused/full tests and focused vet pass. |
|
||||||
| W003 | `TODO` | Move PostgreSQL, Redis, RabbitMQ, external client, and Stellar adapters into infrastructure. | Existing behavior remains available behind inward-facing ports. |
|
| W003 | `DONE` | Move PostgreSQL, Redis, RabbitMQ, external client, and Stellar adapters into infrastructure. | PostgreSQL/Redis, RabbitMQ Watermill, external service, and Stellar/Horizon implementations are infrastructure-owned; legacy implementation imports are removed; full tests, race tests, vet, and build pass. |
|
||||||
| W004 | `TODO` | Extract read-only wallet use cases and gRPC adapters. | Responses and error mapping remain compatible. |
|
| W004 | `DONE` | Extract read-only wallet use cases and gRPC adapters. | Asset, commission, network, price, health, balance, check-balance, transaction-list, asset-catalog, and blockchain-balance reads delegate through `application/walletread`; protobuf conversion and error mapping remain compatible. Wallet-balance synchronization is an explicit mutation deferred to later wallet work. |
|
||||||
| W005 | `TODO` | Extract wallet initialization and asset/trustline use cases. | Transactions, key generation, trustlines, and rollback behavior are tested. |
|
| W005 | `DONE` | Extract wallet initialization and asset/trustline use cases. | `application/walletinit` owns identity/key/trustline policies and orchestration; wallet and trustline-transaction persistence is atomic and shared unit-of-work finalization propagates commit/rollback failures. |
|
||||||
| W006 | `TODO` | Extract deposit, withdrawal, and transaction use cases. | Idempotency, balances, queues, and failure behavior are tested. |
|
| W006 | `DONE` | Extract deposit, withdrawal, and transaction use cases. | Deposit, withdrawal, transfer, settlement-status, balance coordination, locking, idempotent event/outbox, and failure-state behavior are application-owned. Post-settlement fulfillment failures are persisted; the active PSP exposes no reversal operation to call. |
|
||||||
| W007 | `TODO` | Extract market use cases and adapters. | Pricing and market operations remain compatible. |
|
| W007 | `DONE` | Extract market use cases and adapters. | Pricing, validation, order construction/lifecycle, cancellation release, contract policy, and settlement transitions use application services; settlement is synchronous and persists failures deterministically. |
|
||||||
| W008 | `TODO` | Extract alert use cases and adapters. | Alert persistence, delivery, and error behavior remain compatible. |
|
| W008 | `DONE` | Extract alert use cases and adapters. | Alert validation/presentation and context-aware email retry/SMS delivery are application-owned; gRPC is a thin asynchronous delivery adapter. |
|
||||||
| W009 | `TODO` | Extract internal-wallet use cases and adapters. | Internal RPC contracts remain compatible. |
|
| W009 | `DONE` | Extract internal-wallet use cases and adapters. | `application/walletlock` owns load/mutate/save/journal workflow; gRPC retains transaction scope and protocol error mapping through injected persistence/ledger ports. |
|
||||||
| W010 | `TODO` | Separate cron and stream bootstrap from business operations. | Both modes start and stop correctly through explicit dependencies. |
|
| W010 | `DONE` | Separate cron and stream bootstrap from business operations. | Cron and stream have dedicated process composition; stream payment filtering/idempotency/locking/transaction construction is application-owned, and cron receives only its required dependencies. |
|
||||||
| W011 | `TODO` | Replace wallet bootstrap with explicit dependency composition. | All five sub-services work independently and together. |
|
| W011 | `DONE` | Replace wallet bootstrap with explicit dependency composition. | Wallet, market, alert, internal-wallet, cron, and stream use explicit named dependency profiles; legacy generic strict/safe setup entry points are removed. |
|
||||||
| W012 | `TODO` | Remove superseded `core/*Imp` packages and shims. | No duplicate business implementations remain. |
|
| W012 | `DONE` | Remove superseded `core/*Imp` packages and shims. | Runtime adapters live under `interface/grpc` and `interface/process`; `core/*Imp`, legacy package names, duplicate helpers, and compatibility shims are removed. |
|
||||||
|
| W013 | `DONE` | Remove redundant wallet federation creation/model. | Removed federation creation and lookup, wallet federation fields, federation persistence/repository adapters, transaction federation fields/filters, federation protobuf messages, and API documentation/routes. Wallet/Auth/API contracts regenerate and tests pass. |
|
||||||
|
|
||||||
## Phase 4 — `api` architecture
|
## Phase 4 — `api` architecture
|
||||||
|
|
||||||
| ID | Status | Task | Acceptance check / note |
|
| ID | Status | Task | Acceptance check / note |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| G001 | `TODO` | Inventory routes, middleware, response contracts, WebSocket, Swagger, metrics, profiling, and gRPC clients. | Compatibility matrix exists before package moves. |
|
| G001 | `DONE` | Inventory routes, middleware, response contracts, WebSocket, Swagger, metrics, profiling, and gRPC clients. | `ARCHITECTURE-COMPATIBILITY.md` records 57 versioned routes, four auxiliary endpoints, middleware order, envelopes, metadata, Swagger, pprof, WebSocket, and intended peer lifecycle. |
|
||||||
| G002 | `TODO` | Move upstream clients into `infrastructure/grpcclient`. | Lazy connection and two-minute idle-close behavior remain intact. |
|
| G002 | `DONE` | Move upstream clients into `infrastructure/grpcclient`. | Generated clients use a lazy connection interface with serialized dialing, active-call tracking, configurable inactivity closure (two-minute default), reconnection, health checks, explicit close, and focused lifecycle tests. |
|
||||||
| G003 | `TODO` | Move middleware into `interface/http/middleware`. | Existing middleware order is unchanged and tested. |
|
| G003 | `DONE` | Move middleware into `interface/http/middleware`. | The exact APM → profiling → Prometheus → CORS → JSON → i18n → error → optional logger order is centralized and tested; non-verbose profiling now continues the handler chain. |
|
||||||
| G004 | `TODO` | Move public HTTP handlers and routes into `interface/http`. | Public endpoints retain paths, status codes, and envelopes. |
|
| G004 | `DONE` | Move public HTTP handlers and routes into `interface/http`. | Public handlers/routes live under `interface/http/handler`; the complete method/path matrix is asserted and response behavior remains unchanged. |
|
||||||
| G005 | `TODO` | Move authenticated client/admin handlers and routes. | JWT, metadata forwarding, errors, and route behavior remain compatible. |
|
| G005 | `DONE` | Move authenticated client/admin handlers and routes. | Client/admin handlers and authorization routing share the interface boundary; JWT/IAM, header metadata, errors, and all authenticated method/path contracts remain intact. |
|
||||||
| G006 | `TODO` | Move WebSocket and auxiliary endpoints into interface adapters. | WebSocket, health, metrics, Swagger, and profiling still work. |
|
| G006 | `DONE` | Move WebSocket and auxiliary endpoints into interface adapters. | `interface/http` owns router, health, metrics, Swagger URL selection, WebSocket, main HTTP server, pprof server, and graceful shutdown; auxiliary contracts are tested. |
|
||||||
| G007 | `TODO` | Replace API bootstrap with explicit dependency composition. | Gateway builds and all contract tests pass. |
|
| G007 | `DONE` | Replace API bootstrap with explicit dependency composition. | `cmd/apiRuntime` explicitly owns clients, handlers, router, HTTP servers, permission synchronization, shutdown, and client closure; composition and route-count tests pass. |
|
||||||
| G008 | `TODO` | Remove superseded API packages and shims. | No duplicate handlers or clients remain. |
|
| G008 | `DONE` | Remove superseded API packages and shims. | Legacy root `service`, `handler`, `middlewares`, enum-generator/mock shells, dead handler comments, and obsolete dependency are removed; no duplicate clients or handlers remain. |
|
||||||
|
|
||||||
## Phase 5 — AdminPanel write service layer
|
## Phase 5 — AdminPanel write service layer
|
||||||
|
|
||||||
| ID | Status | Task | Acceptance check / note |
|
| ID | Status | Task | Acceptance check / note |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| P001 | `TODO` | Inventory every direct AdminPanel write, delete, inline, bulk action, validation, and side effect. | Each mutation is mapped to an owning Go service or explicitly classified. |
|
| P001 | `DONE` | Inventory every direct AdminPanel write, delete, inline, bulk action, validation, and side effect. | `ADMIN-MUTATION-INVENTORY.md` maps every mutation surface and side effect to its owner or a read-only decision. |
|
||||||
| P002 | `TODO` | Compare required AdminPanel mutations with existing internal RPCs. | Every missing contract is documented before any proto change. |
|
| P002 | `DONE` | Compare required AdminPanel mutations with existing internal RPCs. | The inventory proves asset administration is the only sufficiently specified missing contract. |
|
||||||
| P003 | `TODO` | Add reusable authenticated, deadline-aware gRPC client infrastructure. | Unit tests cover success, timeout, unavailable service, and status translation. |
|
| P003 | `DONE` | Add reusable authenticated, deadline-aware gRPC client infrastructure. | Typed BetterProto/grpclib adapter uses token metadata and configurable deadlines; tests cover success, timeout, unavailable, permission, validation, and status handling. |
|
||||||
| P004 | `TODO` | Add asset application use cases and route asset writes through wallet RPCs. | Direct asset writes stop; access checks and user-visible errors remain correct. |
|
| P004 | `DONE` | Add asset application use cases and route asset writes through wallet RPCs. | Wallet owns upsert/deactivate; AdminPanel never saves or deletes an asset through its ORM, preserves asset access checks, and surfaces RPC failures. |
|
||||||
| P005 | `TODO` | Move token-policy validation and metadata generation to Go-owned operations. | Django no longer owns duplicate wallet business rules. |
|
| P005 | `DONE` | Move token-policy validation and metadata generation to Go-owned operations. | Wallet validates activation/amount policy and derives metadata/token type; duplicate Django logic and related-row auto-generation were removed. |
|
||||||
| P006 | `TODO` | Add wallet and transaction use cases and migrate writes. | Direct writes stop and failure/partial-write behavior is tested. |
|
| P006 | `DONE` | Add wallet and transaction use cases and migrate writes. | Inventory found no valid administrative CRUD: existing Wallet workflows remain the only mutation path and wallet/transaction projections are strictly read-only. |
|
||||||
| P007 | `TODO` | Add market and remaining mutable aggregate use cases. | All classified mutations use their owning service. |
|
| P007 | `DONE` | Add market and remaining mutable aggregate use cases. | Existing lifecycle RPCs remain authoritative; speculative CRUD was rejected and all remaining projections/imports/inlines are read-only. |
|
||||||
| P008 | `TODO` | Make legacy unmanaged ORM models explicitly read-only. | List/detail reads remain fast; migrated writes cannot bypass services. |
|
| P008 | `DONE` | Make legacy unmanaged ORM models explicitly read-only. | Base admin fails closed for unmanaged models; save/delete/bulk/inline/import bypasses are disabled, with a registry-wide regression test. |
|
||||||
| P009 | `TODO` | Fix `no_migartion` to `no_migration` with router tests. | Correct router setting is covered without unintended migrations. |
|
| P009 | `DONE` | Fix `no_migartion` to `no_migration` with router tests. | Router tests prove `coreLogic` never migrates on either database and managed apps remain allowed. |
|
||||||
| P010 | `TODO` | Verify every affected admin page and permission tier. | Create/update/delete/inline/bulk/failure paths pass. |
|
| P010 | `DONE` | Verify every affected admin page and permission tier. | Thirteen focused tests cover registry-wide permissions, asset create/update/deactivate, bulk rejection, service failure, client statuses, and router behavior; Django checks pass. |
|
||||||
|
|
||||||
## Phase 6 — Protobuf contracts
|
## Phase 6 — Protobuf contracts
|
||||||
|
|
||||||
| ID | Status | Task | Acceptance check / note |
|
| ID | Status | Task | Acceptance check / note |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| R001 | `TODO` | Decide whether existing internal RPCs cover all required AdminPanel writes. | Decision is evidence-based; no speculative contract changes. |
|
| R001 | `DONE` | Decide whether existing internal RPCs cover all required AdminPanel writes. | Evidence in `ADMIN-MUTATION-INVENTORY.md` limits new contracts to typed asset administration and rejects generic table mutation. |
|
||||||
| R002 | `TODO` | Add backward-compatible internal RPCs only for proven gaps. | Buf lint/breaking checks pass; existing field numbers and contracts are preserved. |
|
| R002 | `DONE` | Add backward-compatible internal RPCs only for proven gaps. | Additive upsert/deactivate messages and methods pass Buf lint, build, and breaking checks against the prior commit. |
|
||||||
| R003 | `TODO` | Regenerate only active Go and Python consumers. | Generated files are reproducible and Go JSON tags retain required field presence. |
|
| R003 | `DONE` | Regenerate only active Go and Python consumers. | Wallet Go stubs and the AdminPanel's local typed message subset are reproducibly generated; required Go JSON field presence is retained. |
|
||||||
|
|
||||||
## Phase 7 — Shared types and final verification
|
## Phase 7 — Shared types and final verification
|
||||||
|
|
||||||
| ID | Status | Task | Acceptance check / note |
|
| ID | Status | Task | Acceptance check / note |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| F001 | `TODO` | Evaluate shared ID and monetary types after service boundaries stabilize. | Only genuinely identical cross-context semantics are shared. |
|
| F001 | `DONE` | Evaluate shared ID and monetary types after service boundaries stabilize. | `SHARED-TYPES-EVALUATION.md` records the semantic matrix: no candidate has identical cross-context invariants. |
|
||||||
| F002 | `TODO` | Introduce approved shared types incrementally, if justified. | Versioned dependency and explicit boundary conversions are used. |
|
| F002 | `DONE` | Introduce approved shared types incrementally, if justified. | No shared source type is justified. Wallet scale-7 and GL scale-18 values remain local with canonical decimal-string conversion at their versioned boundary. |
|
||||||
| F003 | `TODO` | Run final generation, tests, builds, and architecture checks. | Results meet or exceed the recorded baseline. |
|
| F003 | `DONE` | Run final generation, tests, builds, and architecture checks. | Proto, generated consumers, Django checks/tests, and all Go normal/race/vet/build gates pass; final generation gaps and one test synchronization defect were corrected. |
|
||||||
| F004 | `TODO` | Review every active repository diff for generated/manual/unrelated changes. | Only scoped changes remain and user-owned work is preserved. |
|
| F004 | `DONE` | Review every active repository diff for generated/manual/unrelated changes. | All six active code repositories are clean on `feat/refactor-v1`; regeneration diffs were scoped generated consumers, and the only manual verification diff was the race-test synchronization fix. |
|
||||||
| F005 | `TODO` | Prepare reviewable per-repository commits and final migration report. | Every commit has one purpose and leaves its repository buildable. |
|
| F005 | `DONE` | Prepare reviewable per-repository commits and final migration report. | Scoped API/Auth/Wallet commits are verified and `FINAL-MIGRATION-REPORT.md` records the complete outcome, gates, configuration, and handoff. |
|
||||||
|
|
||||||
## Execution log
|
## Execution log
|
||||||
|
|
||||||
@@ -273,3 +275,87 @@ Append one row whenever a task changes status. Existing rows are never rewritten
|
|||||||
| 2026-08-15 | T008 | `STARTED` | `DONE` | GL built successfully as `darano-gl:go1.26`; API/Auth/Wallet independently reproduced Darano registry gateway timeouts before compilation, with no proxy fallback or source changes introduced. |
|
| 2026-08-15 | T008 | `STARTED` | `DONE` | GL built successfully as `darano-gl:go1.26`; API/Auth/Wallet independently reproduced Darano registry gateway timeouts before compilation, with no proxy fallback or source changes introduced. |
|
||||||
| 2026-08-15 | T009 | `TODO` | `STARTED` | Began adapting the established Go-service Gitea actions and three environment workflows for GL. |
|
| 2026-08-15 | T009 | `TODO` | `STARTED` | Began adapting the established Go-service Gitea actions and three environment workflows for GL. |
|
||||||
| 2026-08-15 | T009 | `STARTED` | `DONE` | Added local build/login/deploy/notify actions plus main/dev/stage workflows; YAML parsing and the exact cached buildx command pass; committed in GL as `675def5`. |
|
| 2026-08-15 | T009 | `STARTED` | `DONE` | Added local build/login/deploy/notify actions plus main/dev/stage workflows; YAML parsing and the exact cached buildx command pass; committed in GL as `675def5`. |
|
||||||
|
| 2026-08-30 | C004 | `CHANGED` | `STARTED` | Resumed Wallet constructor injection after the GL adapter boundary stabilized. |
|
||||||
|
| 2026-08-30 | C004 | `STARTED` | `DONE` | Removed all active global config reads and the legacy facade; injected configuration through every runtime boundary; full tests/race/vet/build pass in the commit series ending at `4d192a6`. |
|
||||||
|
| 2026-08-30 | C005 | `TODO` | `STARTED` | Began API configuration ownership migration. |
|
||||||
|
| 2026-08-30 | C005 | `STARTED` | `DONE` | Moved the pure koanf/TOML loader and compatibility-preserving defaults to `api/infrastructure/config`; loader and full verification pass in `44d56d3`. |
|
||||||
|
| 2026-08-30 | C006 | `TODO` | `STARTED` | Began API global configuration dependency migration. |
|
||||||
|
| 2026-08-30 | C006 | `STARTED` | `DONE` | Removed the API `Cfg` singleton and legacy config package; injected configuration through runtime boundaries; full tests/race/vet/build pass in `44d56d3`. |
|
||||||
|
| 2026-08-30 | L009 | `TODO` | `STARTED` | Began GL reconciliation and disaster-read completion review. |
|
||||||
|
| 2026-08-30 | L009 | `STARTED` | `DONE` | Verified read-only reconciliation, external evidence comparison, duplicate detection, explorer balance reconstruction, and focused tests; implementation commits are `3f5fd86`, `b14c5e2`, and `d5c9b33`. |
|
||||||
|
| 2026-08-30 | L010 | `TODO` | `STARTED` | Began GL outage, replay, ordering, concurrency, and recovery verification. |
|
||||||
|
| 2026-08-30 | L010 | `STARTED` | `DONE` | Full GL tests, race tests, vet, and build pass; replay/idempotency, rollback, conservation/load, ordering, and recovery paths are covered. |
|
||||||
|
| 2026-08-30 | A001 | `TODO` | `STARTED` | Began the method-level Auth RPC and dependency migration map before package moves. |
|
||||||
|
| 2026-08-30 | A001 | `STARTED` | `DONE` | Mapped every public/internal RPC to its use-case operation, persistence ports, external providers, cache, wallet, notification, and configuration dependencies in `REFACTORING-AUDIT.md`. |
|
||||||
|
| 2026-08-30 | A002 | `TODO` | `STARTED` | Began the pure Auth domain model and port foundation. |
|
||||||
|
| 2026-08-30 | A002 | `STARTED` | `DONE` | Added transport/persistence-independent entities, NationalID/Mobile/BirthDate value objects, domain errors, and repository/cache ports; focused and full Auth tests pass in `32f182b`/`d292822`. |
|
||||||
|
| 2026-08-30 | A003 | `TODO` | `STARTED` | Added infrastructure persistence mappings between legacy database records and the new Auth domain entities; mapping tests and full Auth tests pass in `58f6a43`. |
|
||||||
|
| 2026-08-30 | A003 | `STARTED` | `STARTED` | Added remaining persistence mappings and domain-port adapters for sessions, permissions, roles, role-permissions, bank information, and OTP templates; full Auth tests pass in `e6e8e34`. Legacy repository implementations still require relocation/integration. |
|
||||||
|
| 2026-08-30 | A004 | `TODO` | `STARTED` | Extracted OTP code generation and expiration constant into `application/otp`, retained compatible use-case behavior, and added focused tests in `0c92b14`. |
|
||||||
|
| 2026-08-30 | A004 | `STARTED` | `STARTED` | Extracted OTP template parameter decoding into `application/otp`; full Auth tests pass in `62fb1b1`. Legacy template lookup and delivery composition remain. |
|
||||||
|
| 2026-08-30 | A004 | `STARTED` | `STARTED` | Extracted OTP retry/verification policy into `application/otp`; full Auth tests pass in `133fcc3`. Legacy persistence and gRPC composition remain. |
|
||||||
|
| 2026-08-30 | A004 | `STARTED` | `STARTED` | Added transport-independent OTP store and sender contracts in `application/otp`; full Auth tests pass in `8fbfcff`. Concrete Redis/provider adapters remain. |
|
||||||
|
| 2026-08-30 | A004 | `STARTED` | `STARTED` | Added concrete Redis-backed OTP store and Kavenegar sender adapters under `infrastructure/otp`; full Auth tests pass in `cde73ef`. Runtime wiring and gRPC adapter extraction remain. |
|
||||||
|
| 2026-08-30 | A004 | `STARTED` | `STARTED` | Wired OTP store/sender adapters into Auth runtime and use-case paths with legacy fallback retained; full Auth tests pass in `c951875`. |
|
||||||
|
| 2026-08-30 | A004 | `STARTED` | `STARTED` | Wired the OTP template repository port and infrastructure adapter into runtime composition and TFA processing; full Auth tests pass in `741415b`. |
|
||||||
|
| 2026-08-30 | A004 | `STARTED` | `DONE` | Added thin gRPC registration adapters and routed Auth service registration through them; full Auth tests pass in `b56d54c`. |
|
||||||
|
| 2026-08-30 | A005 | `TODO` | `STARTED` | Extracted bearer-token normalization into `application/auth`; full Auth tests pass in `1d72faa`. |
|
||||||
|
| 2026-08-30 | A005 | `STARTED` | `STARTED` | Extracted refresh-token marker validation into `application/auth`; full Auth tests pass in `4225332`. |
|
||||||
|
| 2026-08-30 | A005 | `STARTED` | `STARTED` | Added application JWT verifier contract and infrastructure adapter for access/refresh claims; full Auth tests pass in `ad6f5cc`. |
|
||||||
|
| 2026-08-30 | A005 | `STARTED` | `STARTED` | Injected the JWT verifier into IAM and refresh-token flows with compatibility fallback; full Auth tests pass in `6c5b8cc`. |
|
||||||
|
| 2026-08-30 | A005 | `STARTED` | `STARTED` | Extracted active/expiry session policy into `application/auth`; focused and full Auth tests pass in `424741c`. |
|
||||||
|
| 2026-08-30 | A005 | `STARTED` | `STARTED` | Added and runtime-wired the authentication session-store boundary for IAM retrieval while preserving Redis-expiry behavior; full Auth tests pass in `d744ffc`. |
|
||||||
|
| 2026-08-30 | A005 | `STARTED` | `STARTED` | Routed login and refresh session writes through the authentication session-store boundary with compatibility fallback; full Auth tests and vet pass in `c15bcff`. |
|
||||||
|
| 2026-08-30 | A005 | `STARTED` | `DONE` | Routed refresh lookup through the persistent session boundary (distinct from access-session cache lookup); full Auth tests and vet pass in `016d705`. |
|
||||||
|
| 2026-08-30 | A006 | `TODO` | `STARTED` | Extracted case-insensitive route/method and privileged-role permission policy into `application/permission`; full Auth tests pass in `9f97cec`. |
|
||||||
|
| 2026-08-30 | A006 | `STARTED` | `STARTED` | Runtime-wired the permission repository port for route lookup/creation and super-admin permission listing; full Auth tests pass in `5b61adf`. |
|
||||||
|
| 2026-08-30 | A006 | `STARTED` | `STARTED` | Added and runtime-wired a role-permission reader preserving the existing Redis/Postgres behavior; full Auth tests pass in `24722cb`. |
|
||||||
|
| 2026-08-30 | A006 | `STARTED` | `STARTED` | Added and runtime-wired an identity store over existing cache/persistence behavior, routing identity reads and writes through pure domain models; full Auth tests pass in `113faef`. |
|
||||||
|
| 2026-08-30 | A006 | `STARTED` | `STARTED` | Extracted identity Persian-digit normalization plus birth-date, national-ID, postal-code, and email validation into `application/identity`; full Auth tests pass in `2d5ab3d`. |
|
||||||
|
| 2026-08-30 | A006 | `STARTED` | `DONE` | Added and runtime-wired identity ownership/person-verification boundaries with real/fake provider selection preserved; full Auth tests and vet pass in `75c2e0d`. |
|
||||||
|
| 2026-08-30 | A007 | `TODO` | `DONE` | Replaced the positional Auth constructor with a typed dependency graph assembled explicitly in bootstrap; full Auth tests and vet pass in `7d7871b`. |
|
||||||
|
| 2026-08-30 | A008 | `TODO` | `DONE` | Removed the legacy constructor and superseded runtime fallback implementations across OTP, JWT/session, permission, and identity paths; full Auth tests/race/vet pass in `a9b11a3`. |
|
||||||
|
| 2026-08-30 | A003 | `STARTED` | `DONE` | Relocated all PostgreSQL and Redis implementation files from `repository/db` into `infrastructure`, removed wrapper indirection and the empty Mongo placeholder, and verified no legacy implementation imports remain; full tests/race/vet/build pass in `1323aa4`. |
|
||||||
|
| 2026-08-30 | W001 | `TODO` | `DONE` | Mapped all six wallet runtime modes and their PostgreSQL, Redis, RabbitMQ/outbox, internal/external client, Stellar, availability, cryptography, observability, and shutdown dependencies in `REFACTORING-AUDIT.md`. |
|
||||||
|
| 2026-08-30 | W002 | `TODO` | `DONE` | Added pure wallet entities/value objects, domain errors, filters, repository/cache/UoW ports, and blockchain/internal/external adapter boundaries; focused and full tests plus focused vet pass in `ac649d2`. |
|
||||||
|
| 2026-08-30 | W003 | `TODO` | `STARTED` | Relocated all wallet PostgreSQL and Redis adapter implementations (including tests) from `repository/db` into `infrastructure/postgres` and `infrastructure/redis`; updated bootstrap imports and full Wallet tests pass in `d2580cd`. RabbitMQ, external service, and Stellar adapters remain. |
|
||||||
|
| 2026-08-30 | W003 | `STARTED` | `DONE` | Relocated external service clients to `infrastructure/service` and Stellar/Horizon adapters to `infrastructure/stellar`; updated wallet, market, stream, and bootstrap imports; no legacy implementation imports remain; full tests, race tests, vet, and build pass in `d121fc9`. |
|
||||||
|
| 2026-08-30 | W004 | `STARTED` | `DONE` | Added the `application/walletread` boundary and routed asset, commission, network, price, health, balance, check-balance, transaction-list, asset-catalog, and blockchain-balance reads through it; protobuf conversion and error mapping remain compatible; full Wallet tests pass in `5b17c82`. Wallet-balance synchronization is a mutation deferred to later wallet work. |
|
||||||
|
| 2026-08-30 | W005 | `TODO` | `STARTED` | Added `application/walletinit` for identity preconditions, trustline-limit calculation, key recovery, trustline submission, wallet-code generation, wallet-draft construction, repository-backed find-or-create orchestration, trustline transaction construction, and tested commit/rollback plus existing/create wallet paths; initialization now propagates commit failures; focused Wallet tests pass in `f9a0262`. |
|
||||||
|
| 2026-08-30 | A009 | `TODO` | `DONE` | Removed Auth's commented/dead wallet federation client; Auth tests pass with writable cache in `508a239`. |
|
||||||
|
| 2026-08-30 | W013 | `TODO` | `STARTED` | Removed automatic federation creation and federation lookup from wallet initialization; new wallet records no longer receive a federation assignment; full Wallet tests pass in `97dd9d9`. Remaining schema/API/transaction-field cleanup is pending. |
|
||||||
|
| 2026-08-30 | W013 | `STARTED` | `DONE` | Removed federation persistence/model code, wallet and transaction federation fields, federation protobuf messages, stale API route/docs, and remaining runtime references; regenerated Wallet contracts for Wallet/Auth/API; Wallet, Auth, and API tests pass. Wallet `a38501d`/`7ae90cc`, Auth `446e875`, API `c450264`/`c2c076c`. |
|
||||||
|
| 2026-08-30 | W006 | `TODO` | `STARTED` | Added `application/withdrawal`, `application/deposit`, `application/transfer`, and `application/transaction`; routed IRT reconciliation, IPG conversion/settlement/payer identity, transfer validation, transaction construction/completion, balance-change display policy, deterministic wallet-lock ordering, insufficient-balance failure policy, Stellar status updates, and transaction-event support through application boundaries; invalid event inputs and unsupported transaction types now close safely; focused Wallet tests pass in `66d271e`. Business failure/refund orchestration remains. |
|
||||||
|
| 2026-08-30 | W007 | `TODO` | `STARTED` | Added typed `application/market` policies for agreement tolerance, available amount, raw conversion, positive order inputs, ICO publisher validation, order status codes, and market pricing calculation; market ICO/order validation and calculation delegate through compatibility mapping. Synchronous settlement/stream locking fixed in `3004bb9`; order lifecycle, settlement, contract generation, and adapter extraction remain. |
|
||||||
|
| 2026-08-30 | W008 | `TODO` | `STARTED` | Added `application/alert` level/source label and subject policies plus nil/incomplete-event validation; alert delivery keeps existing asynchronous email/SMS retry behavior. Focused Wallet tests pass in `b3e1dbc`. Delivery, retry, persistence, and adapter extraction remain. |
|
||||||
|
| 2026-08-30 | W010 | `TODO` | `STARTED` | Added `application/cron.Retry`, `application/stream.IsNew`, stream external-deposit transaction policy, and dedicated `SetupCronRepository`/`SetupStreamRepository` paths; cron now avoids nil error telemetry on successful jobs and reads configurable `Cron.Schedule` timing. Focused Wallet tests pass in `5f37e56`. Remaining process composition work remains. |
|
||||||
|
| 2026-08-30 | W009 | `TODO` | `STARTED` | Added `application/walletlock` lock/release mutation policies with frozen/available balance tests; internal RPC retains transaction scope, ledger journaling, persistence, and error mapping, validates incomplete IAM requests safely, and returns explicit success statuses. Focused Wallet tests pass in `0920702`. Remaining internal-wallet operations stay at the service boundary. |
|
||||||
|
| 2026-08-30 | W011 | `TODO` | `STARTED` | Added dedicated alert, market, internal-wallet, stream, cron, and wallet repository setup entry points; each mode now declares its bootstrap profile. Command/core tests pass in `cf13a58`. Dependency internals and superseded bootstrap cleanup remain. |
|
||||||
|
| 2026-08-30 | W012 | `TODO` | `STARTED` | Removed redundant market amount/agreement, IPG amount/payer-ID, referral-commission, redeem-allocation, contract-rounding, and agreement-ID implementations; discount, referral, redeem arithmetic, and contract policies now live in application packages. Focused Wallet tests pass in `dc0bdf4`. Remaining core implementation cleanup is pending. |
|
||||||
|
| 2026-08-31 | W005 | `STARTED` | `DONE` | Completed wallet initialization/trustline orchestration, atomic trustline-transaction persistence, and shared unit-of-work finalization; all Wallet validation gates pass through `240b8d0`. |
|
||||||
|
| 2026-08-31 | W006 | `STARTED` | `DONE` | Extracted transaction balance processing, deterministic locking and status transitions, persisted post-PSP fulfillment failures, and retained idempotent transaction/ledger outboxes. The active Vandar contract has no refund/reversal operation, so no speculative provider call was introduced; all validation gates pass through `240b8d0`. |
|
||||||
|
| 2026-08-31 | W007 | `STARTED` | `DONE` | Extracted market order lifecycle and settlement transitions, made settlement synchronous, persisted failures, and released canceled maker balances; all validation gates pass through `240b8d0`. |
|
||||||
|
| 2026-08-31 | W008 | `STARTED` | `DONE` | Extracted context-aware alert delivery and retry behavior behind application ports and reduced gRPC to transport/adaptation; all validation gates pass through `240b8d0`. |
|
||||||
|
| 2026-08-31 | W009 | `STARTED` | `DONE` | Extracted lock/release persistence and ledger-journal workflow behind function ports while retaining transaction and protocol mapping at the gRPC boundary; all validation gates pass through `240b8d0`. |
|
||||||
|
| 2026-08-31 | W010 | `STARTED` | `DONE` | Extracted the Stellar stream payment workflow, narrowed cron/stream composition, and removed duplicate cron registration; all validation gates pass through `240b8d0`. |
|
||||||
|
| 2026-08-31 | W011 | `STARTED` | `DONE` | Replaced generic bootstrap internals with explicit process dependency profiles and removed legacy strict/safe setup names; all validation gates pass through `240b8d0`. |
|
||||||
|
| 2026-08-31 | W012 | `STARTED` | `DONE` | Moved adapters out of `core`, removed duplicate helpers/shims, renamed legacy `*Imp` packages to interface-owned names, and verified no legacy core/bootstrap references remain; all validation gates pass through `240b8d0`. |
|
||||||
|
| 2026-08-31 | G001 | `TODO` | `DONE` | Recorded the pre-move route, middleware, envelope, metadata, auxiliary endpoint, Swagger/pprof/WebSocket, and peer lifecycle compatibility matrix in API `95c4264`. |
|
||||||
|
| 2026-08-31 | G002 | `TODO` | `DONE` | Added the application upstream port and lazy reconnecting gRPC infrastructure with inactivity and explicit-close tests in API `0edea98`. |
|
||||||
|
| 2026-08-31 | G003 | `TODO` | `DONE` | Moved middleware below `interface/http`, centralized/tested its exact order, and fixed the non-verbose chain stop in API `1d9b6ca`. |
|
||||||
|
| 2026-08-31 | G004 | `TODO` | `DONE` | Moved public handlers/routes below `interface/http/handler` and locked the public method/path matrix in API `41fac0c`. |
|
||||||
|
| 2026-08-31 | G005 | `TODO` | `DONE` | Moved authenticated client/admin handlers and authorization routing into the same tested interface boundary in API `41fac0c`. |
|
||||||
|
| 2026-08-31 | G006 | `TODO` | `DONE` | Extracted router, health, metrics, Swagger, WebSocket, HTTP/pprof server ownership, and graceful shutdown into `interface/http` in API `380aad4`. |
|
||||||
|
| 2026-08-31 | G007 | `TODO` | `DONE` | Added explicit typed API runtime composition with startup permission synchronization and owned cleanup in API `163114f`. |
|
||||||
|
| 2026-08-31 | G008 | `TODO` | `DONE` | Removed legacy service/handler/middleware packages, generated enum/mock shims, dead shells, and unused dependencies in API `31e3043`; protobuf/Swagger regeneration, tests, race, vet, build, and whitespace checks pass. |
|
||||||
|
| 2026-08-31 | P001–P002 / R001 | `TODO` | `DONE` | Audited every AdminPanel mutation surface and existing internal RPC, documenting why asset administration is the sole proven contract gap and why arbitrary wallet, transaction, market, auth, and configuration CRUD must remain disabled. |
|
||||||
|
| 2026-08-31 | R002–R003 | `TODO` | `DONE` | Added additive authenticated asset upsert/deactivate contracts, passed Buf lint/build/breaking checks, regenerated Wallet Go stubs, and made the AdminPanel Python subset locally reproducible. |
|
||||||
|
| 2026-08-31 | P003–P010 | `TODO` | `DONE` | Added the deadline/token-aware Wallet client; moved asset policy and persistence into Wallet; made every other unmanaged admin, inline, import, delete, and signal path fail closed; fixed the migration router; full Wallet tests plus thirteen AdminPanel boundary tests and Django checks pass. |
|
||||||
|
| 2026-09-01 | F001 | `TODO` | `STARTED` | Began a code-backed comparison of identifier and monetary semantics across Proto, Auth, Wallet, API, and GL before approving any shared representation. |
|
||||||
|
| 2026-09-01 | F001 | `STARTED` | `DONE` | Documented differing Wallet/GL precision, arithmetic, persistence, identifier ownership, signedness, and opaque-ID semantics in `SHARED-TYPES-EVALUATION.md`; no universal type is safe. |
|
||||||
|
| 2026-09-01 | F002 | `TODO` | `DONE` | Concluded that no new shared implementation is justified; retained independently versioned domain types and the existing lossless canonical decimal-string service boundary. |
|
||||||
|
| 2026-09-01 | F003 | `TODO` | `STARTED` | Began final reproducible generation, tests, race checks, vet, builds, Django checks, and architecture scans across every active repository. |
|
||||||
|
| 2026-09-01 | F003 | `STARTED` | `DONE` | Passed Buf lint/build/breaking, local Python and all Go generation, thirteen AdminPanel tests/checks, and API/Auth/Wallet/GL tests/race/vet/build. Committed missing API/Auth generated Wallet contracts and corrected Wallet integration-test synchronization found by the race gate. |
|
||||||
|
| 2026-09-01 | F004 | `TODO` | `STARTED` | Began final per-repository status, generated/manual diff, branch, architecture-documentation, and unrelated-change review across all active repositories. |
|
||||||
|
| 2026-09-01 | F004 | `STARTED` | `DONE` | Confirmed API/Auth/Wallet/GL/AdminPanel/Proto are clean on `feat/refactor-v1`; reviewed generated admin-contract diffs and the Wallet test-only synchronization diff; refreshed stale architecture guidance without modifying excluded repositories. |
|
||||||
|
| 2026-09-01 | F005 | `TODO` | `DONE` | Prepared purpose-specific generated-consumer and test commits plus `FINAL-MIGRATION-REPORT.md`; every active repository remains buildable and no actionable tracker task remains. |
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
# Shared ID and monetary type evaluation
|
||||||
|
|
||||||
|
Date: 2026-09-01
|
||||||
|
Scope: `api`, `auth`, `wallet`, `GL`, `proto`, and `AdminPanel`
|
||||||
|
Tasks: `F001`, `F002`
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
No new cross-repository source package or universal protobuf wrapper is approved.
|
||||||
|
The superficially similar values do not currently have identical invariants. Keep
|
||||||
|
domain value objects local and perform explicit conversion at service boundaries.
|
||||||
|
|
||||||
|
This is a positive architectural decision, not deferred implementation. A shared
|
||||||
|
type may be proposed later only if its producer, consumers, precision, nullability,
|
||||||
|
validation, versioning, and compatibility behavior are proven identical.
|
||||||
|
|
||||||
|
## Monetary semantics
|
||||||
|
|
||||||
|
| Context | Representation | Invariants | Decision |
|
||||||
|
|---|---|---|---|
|
||||||
|
| Wallet domain | `domain/money.Amount`, fixed-scale integer units backed by `big.Int` | Scale 7; mirrors `numeric(23,7)` and Stellar stroops; supports exact wallet arithmetic and explicit legacy `float64` conversion | Keep Wallet-owned. |
|
||||||
|
| Wallet nullable persistence values | `money.NullAmount` | Distinguishes SQL null from zero | Keep Wallet-owned; nullability is persistence/domain-specific. |
|
||||||
|
| GL domain | `domain/ledger.Amount`, fixed-scale `big.Int` | Precision 38, scale 18; canonical parsing; immutable double-entry journal values | Keep GL-owned. It intentionally has more precision and stricter canonical input than Wallet. |
|
||||||
|
| Wallet ↔ GL contract | Canonical base-10 `string` in `ledger.v1.JournalEntry.amount` | Lossless, language-neutral boundary; Wallet formats its exact amount and GL reparses under GL constraints | Retain. This is the correct explicit conversion boundary. |
|
||||||
|
| Existing public Wallet/Market contracts | `double` plus some integer IRR/raw values | Backward-compatibility surface with explicit conversion/finite/range checks inside Wallet | Do not replace during this refactor; changing wire types is breaking. Track separately if a versioned v2 contract is approved. |
|
||||||
|
| AdminPanel | Python `Decimal`/Django decimal fields, serialized to canonical strings for asset administration | Projection/form representation; Wallet owns final validation | Keep adapter-local. |
|
||||||
|
|
||||||
|
Why Wallet and GL amounts must not be aliased:
|
||||||
|
|
||||||
|
- scale 7 and scale 18 represent different accepted value sets;
|
||||||
|
- their database precision limits differ;
|
||||||
|
- Wallet includes Stellar raw-unit conversion and commercial rounding operations;
|
||||||
|
- GL requires canonical journal serialization, conservation, and immutable audit precision;
|
||||||
|
- importing either implementation into the other repository would reverse the service dependency direction;
|
||||||
|
- a common implementation would still require context-specific wrappers, eliminating its claimed benefit.
|
||||||
|
|
||||||
|
## Identifier semantics
|
||||||
|
|
||||||
|
| Identifier family | Current representation | Meaning | Decision |
|
||||||
|
|---|---|---|---|
|
||||||
|
| Auth/User/Identity database IDs | Predominantly signed `int64`; national ID is validated `auth/model.NationalID` string | Auth-owned persistence identity versus a regulated external identifier | Keep `NationalID` Auth-owned. Do not conflate it with database IDs. |
|
||||||
|
| Wallet asset/user/transaction IDs | Predominantly signed `int64` | Positive database keys; zero commonly represents absent/default at protobuf boundaries | Keep explicit field names and validate positivity per operation. |
|
||||||
|
| Wallet market/order/legacy entity IDs | Mixture of `uint`, `uint64`, and `int64` | Historical GORM/protobuf choices with deployed wire compatibility | Do not hide signedness differences behind a shared alias. Normalize only in a versioned migration with database and protobuf evidence. |
|
||||||
|
| GL journal/event IDs | `string` | Service-generated opaque IDs, not database sequence numbers | Keep opaque strings. |
|
||||||
|
| GL source transaction/actor/owner IDs | `string` | Cross-service references supporting multiple owner/source namespaces | Keep strings and explicit source/owner type; converting to numeric IDs would remove namespace flexibility. |
|
||||||
|
| Generic `base.v1.IdReq`/`IdRes` | `int64` | Existing transport convenience only | Retain for compatibility, but do not use it as a domain-wide ID abstraction. |
|
||||||
|
|
||||||
|
A source-level `UserID`, `AssetID`, or generic `ID` package is not approved because:
|
||||||
|
|
||||||
|
- repositories are independently versioned and should not acquire a shared-code release dependency;
|
||||||
|
- protobuf field types are already deployed and inconsistent across legacy contracts;
|
||||||
|
- aliases would not enforce positivity, ownership, namespace, or existence;
|
||||||
|
- strong local types are useful only when named for a bounded context and validated there;
|
||||||
|
- API is an adapter and should map contracts, not become the owner of domain identity types.
|
||||||
|
|
||||||
|
## Approved boundary rules
|
||||||
|
|
||||||
|
1. Financial values crossing new internal boundaries use canonical base-10 strings
|
||||||
|
when exact decimal fidelity is required.
|
||||||
|
2. Each receiving service parses into its own domain amount and applies its own
|
||||||
|
precision, sign, and business rules.
|
||||||
|
3. IDs remain explicitly named (`user_id`, `asset_id`, `journal_id`, etc.); generic
|
||||||
|
IDs must not cross a boundary without the message or operation supplying meaning.
|
||||||
|
4. Opaque IDs remain strings. Database sequence IDs retain their deployed signedness
|
||||||
|
until a separately versioned contract migration is justified.
|
||||||
|
5. `float64` money is allowed only at existing compatibility edges; new domain code
|
||||||
|
must use exact local values.
|
||||||
|
6. No service imports another service's domain package. Generated protobuf contracts
|
||||||
|
and explicit adapter conversions remain the sharing mechanism.
|
||||||
|
|
||||||
|
## F002 outcome
|
||||||
|
|
||||||
|
There are no approved shared types to introduce. Therefore F002 completes with no
|
||||||
|
runtime or contract change. The existing Wallet-to-GL canonical decimal string is
|
||||||
|
already the correct shared representation at the boundary, while both sides retain
|
||||||
|
their distinct domain types.
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
# Darano discovery progress
|
||||||
|
|
||||||
|
Updated: 2026-08-28 (Asia/Tehran)
|
||||||
|
|
||||||
|
## Step 1 — workspace inventory
|
||||||
|
|
||||||
|
- The workspace is an aggregate of independent repositories: `api`, `auth`, `wallet`, `GL`, `ui`, `AdminPanel`, `proto`, `DevOps`, `docs`, `alert`, and Kuknos node scripts.
|
||||||
|
- `api` is the public REST gateway; Go backends communicate over gRPC. The customer UI is Next.js. The admin surface is Django and currently has direct database access.
|
||||||
|
- Prior-machine planning and refactoring records are present in `dev-procfile/`. They include completed work on a transactional outbox and event-driven wallet transaction processing, plus unfinished GL and admin-integration work.
|
||||||
|
- Repository-specific instructions were read before analysis. Existing user changes will be preserved.
|
||||||
|
|
||||||
|
## Next checks
|
||||||
|
|
||||||
|
- Reconcile TODO claims with current code and Git history.
|
||||||
|
- Trace business domains and every user transaction entry point through settlement.
|
||||||
|
- Audit GL capabilities and the Kuknos/GL source-of-truth switch.
|
||||||
|
- Run and assess relevant test suites.
|
||||||
|
- Compare the staging product with the implemented UI/API where access permits.
|
||||||
|
- Produce the final concise report and mind map in this directory.
|
||||||
|
|
||||||
|
## Current limitation
|
||||||
|
|
||||||
|
- The interactive browser surface is unavailable in this session. Staging-site inspection will use read-only web access; any authenticated-only behavior may require user-provided access or screenshots.
|
||||||
|
|
||||||
|
## Step 2 — recovered-work reconciliation
|
||||||
|
|
||||||
|
- The tracker is internally consistent with Git history for `wallet`, `auth`, and `proto`: their refactor branches contain the cited commits.
|
||||||
|
- The local `GL` checkout is misleadingly on `main` (initial README/license only). The complete GL implementation and explorer are present, identically, on `origin/dev` and `origin/feat/refactor-v1` at `32e7b6b`.
|
||||||
|
- The root `Procfile` does not start GL or its explorer, and the checked-in stage compose/config does not deploy or configure GL. Therefore “start the main app and write alongside Stellar” is not true for the current aggregate startup/deployment despite the service and wallet adapters existing on feature branches.
|
||||||
|
- The accepted GL design deliberately excludes automatic failover. It defines `MIRROR`, future admin-authorized `DEGRADED_LEDGER`, and `RECONCILE`, but only mirror recording is implemented so far.
|
||||||
|
- The event pipeline is real code, not merely a plan: transaction persistence atomically creates a per-type outbox event; Watermill/RabbitMQ dispatches it; an idempotent inbox handler runs the legacy processor; retries and deadbox handling exist. It starts only in wallet service mode.
|
||||||
|
|
||||||
|
## Early risks to verify
|
||||||
|
|
||||||
|
- GL journals currently originate from Wallet `float64` amounts formatted to seven decimal places; GL itself correctly expects fixed-point decimal strings. This boundary can preserve pre-existing rounding error and is weaker than the stated `numeric(38,18)` invariant.
|
||||||
|
- Transaction lifecycle event version is hard-coded to `1`, while the idempotency key hashes the payload. Multiple state changes for one transaction may conflict with GL's unique source-transaction/event-version constraint; this needs a test/code-path check.
|
||||||
|
- The transaction-event consumer reports success alerts even when it receives a duplicate event for a transaction already marked successful. Inbox idempotency prevents repeat handling after a succeeded inbox claim, but crash windows around notification vs. inbox completion need review.
|
||||||
|
|
||||||
|
## Step 3 — staging-flow reconciliation
|
||||||
|
|
||||||
|
- User screenshots confirm available/locked/total balances, asset actions, transaction history, market maker/taker purchase, ICO purchase from a selected maker, legal agreement acceptance, verified Sheba accounts, IRT withdrawal, and referrals.
|
||||||
|
- Product clarification adds five required workflows: Kuknos subscription, bank-deposit ingestion, IPG confirmation, admin-approved IRT withdrawal, and third-party collateral locks.
|
||||||
|
- Every transaction may require SMS, TOTP, or email 2FA plus a versioned agreement/contract/policy acceptance. These are prerequisites and immutable audit evidence, not incidental UI steps.
|
||||||
|
- GL was switched from `main` to the canonical `feat/refactor-v1` branch. Its tracked license was restored after a checkout filesystem anomaly; the pre-existing `.DS_Store` was preserved.
|
||||||
|
|
||||||
|
## Step 4 — availability policy
|
||||||
|
|
||||||
|
- GL is confirmed as a mandatory transaction dependency. There is no GL operational failover mode: GL failure must halt every value-changing workflow until recovery.
|
||||||
|
- `/health` must become critical/not-ready and the incident/recovery transitions must be reported through OpenTelemetry logs (with metrics/traces recommended for correlation).
|
||||||
|
- Current behavior violates this policy: Wallet health is unconditional success, GL remains `Serving=true` when its database ping fails, API health does not aggregate GL, and the asynchronous ledger dispatcher only logs/retries while transactions continue.
|
||||||
|
- Automatic acceptance policy for third-party collateral transactions is out of scope and retained as a future feature.
|
||||||
|
|
||||||
|
## Step 5 — authority and Kuknos mode
|
||||||
|
|
||||||
|
- GL is the primary append-only financial source of truth. Kuknos is the secondary settlement and verification source.
|
||||||
|
- Normal operation requires both. GL outage always halts transactions. Kuknos outage also halts transactions until an authorized operator explicitly enables GL-only `KUKNOS_DISABLED` mode through AdminPanel or configuration.
|
||||||
|
- The mode may not switch automatically. Its actor, reason, time, previous/new state, and recovery/reconciliation must be auditable and sent through OpenTelemetry.
|
||||||
|
- Append-only enforcement is present in GL database triggers and reversal validation.
|
||||||
|
|
||||||
|
## Step 6 — implementation
|
||||||
|
|
||||||
|
- Implemented the GL/Kuknos fail-closed gate at mutation RPC, transaction worker, health, and Kuknos subscription boundaries.
|
||||||
|
- Added the explicit configuration switch `network.kuknos-enabled`; no automatic switch or automatic acceptance policy was added.
|
||||||
|
- Corrected GL database readiness, API HTTP 503 health propagation, and structured OTel-compatible incident/recovery logs.
|
||||||
|
- Wallet and GL full test suites pass. Details and remaining atomicity/deployment limits are in `05-availability-implementation.md`.
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Project index
|
||||||
|
|
||||||
|
| Repository | Purpose | Main domain |
|
||||||
|
|---|---|---|
|
||||||
|
| `ui` | Next.js customer site and dashboard | onboarding, assets, buy/redeem, market, history |
|
||||||
|
| `api` | Only public HTTP gateway; translates REST to gRPC | API/auth boundary |
|
||||||
|
| `auth` | OTP, JWT, TFA, identity, bank info, roles/permissions | identity and access |
|
||||||
|
| `wallet` | Wallet, asset, transaction, market, IPG, BNPL, redeem, alert workers | financial orchestration |
|
||||||
|
| `GL` | Append-only double-entry ledger and explorer | backup financial truth |
|
||||||
|
| `AdminPanel` | Django operations console with direct shared-DB access | manual administration |
|
||||||
|
| `proto` | Versioned gRPC contracts | service boundary |
|
||||||
|
| `DevOps` | Compose, Traefik, databases, Redis, RabbitMQ, MinIO, monitoring | runtime platform |
|
||||||
|
| `Kuknos-Node-scripts` | Kuknos/Stellar node operations | blockchain infrastructure |
|
||||||
|
| `docs` | Product documentation | documentation |
|
||||||
|
| `alert` | Legacy/minimal alert repository; active alert server is in Wallet | notifications |
|
||||||
|
|
||||||
|
## Runtime shape
|
||||||
|
|
||||||
|
`Browser -> UI -> API -> Auth / Wallet / Market / Alert`
|
||||||
|
|
||||||
|
Wallet uses PostgreSQL and Redis, submits blockchain work through the Stellar-compatible Kuknos adapter, and publishes durable transaction events through RabbitMQ. Wallet also has a separate durable outbox that mirrors lifecycle events and successful monetary effects to GL.
|
||||||
|
|
||||||
|
## Branch reality
|
||||||
|
|
||||||
|
- Refactor code is active in `wallet`, `auth`, `proto`, and `AdminPanel` feature branches.
|
||||||
|
- Full GL code is now checked out on `GL/feat/refactor-v1`, tracking `origin/feat/refactor-v1`.
|
||||||
|
- `api` and `dev-procfile` have no local or remote `feat/refactor-v1` ref in this checkout; both remain on `main` rather than inventing an untracked branch lineage.
|
||||||
|
- Stage compose currently deploys API/Auth/Wallet/Admin/UI, but not GL or the GL explorer.
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Business-domain map
|
||||||
|
|
||||||
|
## Core domains
|
||||||
|
|
||||||
|
- Tokenization: asset definition, issuer/network metadata, price, supply/buy limits, policy, whitelist, and publisher-owned ICO sell orders.
|
||||||
|
- Custody and settlement: user wallets, Kuknos trustlines, internal/external transfer, deposit/withdrawal, balance locks, commissions, and blockchain tracking.
|
||||||
|
- Primary sale: quote -> agreement -> claim-once acceptance -> taker order -> settlement against the authorized token publisher's live maker order.
|
||||||
|
- Secondary market: buy/sell orders, contracts, matching/settlement, cancellation, history, and market clearing.
|
||||||
|
- Fiat rails: Mellat IPG deposit confirmation, IRT withdrawal approval, accounting and withdrawal logs.
|
||||||
|
- Redemption: token return, repayment calculation, bank destination, and operational payout record.
|
||||||
|
- IAM/compliance: OTP/JWT/TFA, identity/KYC data, bank accounts, roles, route permissions, and asset-level admin permissions.
|
||||||
|
- Financing: BNPL plans, applications, companies, schedules, supported assets, and locked balances.
|
||||||
|
- Audit/accounting: Wallet transaction lifecycle, immutable GL journals/events, balances, replay, and explorer.
|
||||||
|
- Legal evidence: versioned agreements/contracts/policies, acceptance, signer, 2FA proof, and transaction linkage.
|
||||||
|
- Collateral authorization: third-party API clients, scoped lock requests, approval/denial, reservation, release, and consumption.
|
||||||
|
|
||||||
|
## Key invariants already expressed
|
||||||
|
|
||||||
|
- GL monetary journals are immutable, atomic, idempotent, fixed-point, and balanced per asset.
|
||||||
|
- A primary-sale maker must be an open ICO sell order owned by a user with the stable `token-publisher` role.
|
||||||
|
- Agreement acceptance is claim-once; settlement rechecks price, commission, order status, and remaining volume.
|
||||||
|
- Transaction inserts and GL/event outbox writes share the Wallet database transaction.
|
||||||
|
- A market/ICO operation must reserve spend and inventory before asynchronous execution; rejection or failure must release the same reservation exactly once.
|
||||||
|
- IRT withdrawal is a stateful approval workflow, not a direct transfer: request -> freeze -> admin decision -> settle/release.
|
||||||
|
|
||||||
|
## Ownership problem
|
||||||
|
|
||||||
|
AdminPanel can still mutate unmanaged replicas of core tables directly. These writes bypass Wallet validation, Kuknos operations, transaction events, and GL recording. Until mutations go through authenticated internal RPCs and legacy models become read-only, the business invariants are not system-wide.
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Event, GL, and test audit
|
||||||
|
|
||||||
|
## User transaction events
|
||||||
|
|
||||||
|
Status: partially correct, not reliable enough yet.
|
||||||
|
|
||||||
|
- Good: each transaction insert atomically creates a durable RabbitMQ outbox record; delivery has retries/deadbox; consumption has an idempotent inbox.
|
||||||
|
- Critical: the event is created only once, at initial insert. Transfers and redeem are inserted as `CREATED`; if consumed before confirmation, the handler rejects/retries and can dead-letter. Later status updates do not refresh/re-enqueue it because transaction ID and payload are immutable.
|
||||||
|
- Only `BUY`, `SELL`, `INTERNAL_TRANSFER`, and `REDEEM` are executable by the event processor. Other declared topics—including IRT deposit/withdrawal, external transfer, commission, lock, and trustline—cannot be processed by it.
|
||||||
|
- Several user flows still execute synchronously: external Kuknos transfers, Mellat/IPG steps, IRT withdrawal, and ICO/market settlement. The current pipeline therefore does not satisfy “user-side transaction requests are event driven” as a general invariant.
|
||||||
|
|
||||||
|
Recommended contract: persist a command/request event only after validation and TFA, use a unique command ID plus state/version, let a worker own side effects, and expose request status to the client. Lifecycle events should be separate facts, not reuse a single immutable command row.
|
||||||
|
|
||||||
|
The clarified product flows require separate event-driven process managers for market/ICO settlement, Kuknos ingestion, bank/IPG deposits, IRT withdrawal approval, and third-party collateral locks. Each must persist 2FA and agreement evidence before emitting an executable command.
|
||||||
|
|
||||||
|
## GL
|
||||||
|
|
||||||
|
Status: primary append-only source of truth; current integration still behaves as an asynchronous mirror.
|
||||||
|
|
||||||
|
- The feature branch implements double-entry journals, lifecycle events, idempotency, immutable PostgreSQL storage, balance queries, replay, and a localized explorer.
|
||||||
|
- Required availability policy: fail closed. When GL or its database is unhealthy, reject/pause all new value-changing commands and pause transaction workers until GL recovers. Reads may remain available but `/health` must report `CRITICAL`/not-ready.
|
||||||
|
- Normal mode requires both GL and Kuknos. Kuknos is the secondary settlement/verification truth. Its outage also halts transactions unless an operator explicitly activates `KUKNOS_DISABLED` through AdminPanel or configuration.
|
||||||
|
- `KUKNOS_DISABLED` must never activate automatically. Mode changes require authorization, immutable audit evidence, OTel telemetry, and reconciliation before/after returning to normal.
|
||||||
|
- Implemented: shared readiness gate at Wallet/Internal/Market mutation RPCs and transaction workers; GL database-aware health; API critical/503 propagation; structured OTel-compatible transition logs; config-only Kuknos switch; local/config wiring.
|
||||||
|
- Still missing: persisted/AdminPanel mode control, hysteresis, metrics/traces, concrete compose GL deployment, reconciliation tooling, broad outage/concurrency acceptance tests, trustline state, and reservation ownership/reason semantics.
|
||||||
|
- Health polling alone has a race: GL can fail after the check but before a Wallet commit or external Kuknos/IPG submission. A strict “no transaction commits while GL is unavailable” guarantee requires an acknowledged GL write/prepare step or a formal saga; an asynchronous outbox plus preflight check cannot provide that guarantee by itself.
|
||||||
|
- Money risk: Wallet stores and maps `float64`, then formats only seven decimal places before GL. GL's `numeric(38,18)` cannot recover precision already lost upstream.
|
||||||
|
- Lifecycle risk: GL event version is always `1`; multiple transaction states may collide at the GL uniqueness boundary.
|
||||||
|
- Append-only verification: PostgreSQL triggers reject journal deletion, entry/account/event update or deletion, and entry insertion after journal sealing. Corrections are exact reversing journals; the original record remains intact.
|
||||||
|
|
||||||
|
## Tests run on 2026-08-28
|
||||||
|
|
||||||
|
- GL feature branch in isolated copy: `go test ./...` passed.
|
||||||
|
- Wallet: full `go test ./...` passes after replacing the invalid dependency on ignored secret config fixtures with explicit default/override tests.
|
||||||
|
- API: health tests pass in an isolated copy populated with compatible generated stubs; the checkout still needs its normal `buf generate` step. Auth was not changed.
|
||||||
|
- Coverage gap: most `core/walletImp` user flows have no package tests. Existing event tests prove infrastructure mechanics but miss the `CREATED -> confirmed -> PENDING_TRX` race described above.
|
||||||
|
|
||||||
|
Minimum logical acceptance tests: GL-down admission rejection, workers paused while GL is critical, recovery without duplicate execution, failure between health check and commit, duplicate commands, broker/Kuknos/IPG outage, crash after external submission, state-version ordering, concurrent spend/lock, partial maker fills, whitelist rejection, amount precision, 2FA/agreement evidence, admin approve/deny, reconciliation, and a full request-to-final-status test for every transaction type.
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# Product flows confirmed from staging screenshots
|
||||||
|
|
||||||
|
## Wallet and balances
|
||||||
|
|
||||||
|
- Portfolio shows total value, available value, locked value, per-asset balance/value/price, and allowed actions.
|
||||||
|
- “Locked” is a first-class user-visible balance. GL must expose at least `available`, `locked`, and `total = available + locked` per user/asset, with the lock reason and owning operation.
|
||||||
|
- History exposes asset, time, amount, transaction type, state, tracking number, and Kuknos/hash-like reference.
|
||||||
|
|
||||||
|
## Transaction gate
|
||||||
|
|
||||||
|
Every value-changing request can require configurable 2FA (`SMS`, `TOTP`, or `EMAIL`) and an agreement acceptance. An agreement may be:
|
||||||
|
|
||||||
|
- a generated legal contract;
|
||||||
|
- transaction-specific terms and conditions; or
|
||||||
|
- acceptance of site/platform policy.
|
||||||
|
|
||||||
|
The accepted agreement version, content hash, actor, transaction/request ID, timestamp, and 2FA method/result must be immutable audit evidence.
|
||||||
|
|
||||||
|
## Trade and ICO
|
||||||
|
|
||||||
|
- Secondary market: maker posts an order; taker accepts all or part of its remaining quantity. Contract acceptance precedes settlement.
|
||||||
|
- ICO: taker buys only from a specific authorized publisher maker order. Asset/user whitelisting may reject the request before agreement/settlement.
|
||||||
|
- Reserved quantities and balances must be locked atomically when an order/request becomes executable, then consumed or released exactly once.
|
||||||
|
|
||||||
|
## Money movement
|
||||||
|
|
||||||
|
- Kuknos subscription imports observed blockchain transactions/deposits.
|
||||||
|
- External bank deposit causes IRT issuance/transfer from the server treasury to the user.
|
||||||
|
- IPG flow: create gateway token -> redirect -> confirm callback -> transfer IRT from treasury.
|
||||||
|
- IRT withdrawal: create request -> freeze IRT -> 2FA/agreement if required -> admin approve/deny -> finalize state and consume/release lock.
|
||||||
|
- Authorized third party: API-token request -> manual/user/admin decision -> lock asset as collateral -> success, denied, or failed result; later release/consume must reference the original lock. Automatic acceptance policy is explicitly a future feature.
|
||||||
|
|
||||||
|
## Platform availability rule
|
||||||
|
|
||||||
|
- GL is the primary, append-only source of truth and is mandatory for every value-changing workflow.
|
||||||
|
- Kuknos is the secondary settlement/verification source of truth. `NORMAL` mode requires both GL and Kuknos.
|
||||||
|
- GL/GL-database failure puts transaction admission and transaction workers into a fail-closed halt until health is restored.
|
||||||
|
- Kuknos failure also halts transactions unless an authorized operator explicitly selects `KUKNOS_DISABLED` using AdminPanel or configuration. There is no automatic switch.
|
||||||
|
- Public health must expose the incident as critical/not-ready, and transitions into, during, and out of the incident must be observable through OpenTelemetry.
|
||||||
|
- Non-mutating views can remain available if their data can be labelled consistently and safely.
|
||||||
|
|
||||||
|
## Bank and referral
|
||||||
|
|
||||||
|
- Bank information maintains verified Sheba/IBAN accounts; the account must belong to the identified user before withdrawal.
|
||||||
|
- Referral tracks invitation code/link, referred users, commission share, received/withdrawable reward, and reward withdrawal.
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# Availability implementation
|
||||||
|
|
||||||
|
Implemented on `feat/refactor-v1` on 2026-08-28.
|
||||||
|
|
||||||
|
- Added one fail-closed financial availability gate shared by Wallet, Internal Wallet, Market, and transaction workers.
|
||||||
|
- Normal mode requires healthy GL (including its database) and Kuknos Horizon. `network.kuknos-enabled=false` is the explicit, startup-time GL-only switch; it never changes automatically.
|
||||||
|
- Mutation RPCs return gRPC `UNAVAILABLE` during an outage. Read-only RPCs remain available; unknown future RPCs are treated as mutations.
|
||||||
|
- Transaction event outbox/inbox workers pause before claiming work. Dependency outages do not dead-letter business events.
|
||||||
|
- Kuknos subscription blocks its callback during a GL outage so the Horizon cursor cannot advance past an unrecorded external deposit; the streamer pauses entirely when Kuknos is manually disabled.
|
||||||
|
- GL health now reports not-serving when PostgreSQL is unavailable. Wallet/Market health propagates the gate, and the public API returns HTTP 503 with `status=critical`.
|
||||||
|
- Availability transition/recovery logs are structured JSON on stderr for the existing OTel collector. Outages use `CRITICAL`; recovery uses `INFO`.
|
||||||
|
- Added GL to the development Procfile and explicit GL/availability/Kuknos settings to dev, stage, and main service configs.
|
||||||
|
|
||||||
|
Verification:
|
||||||
|
|
||||||
|
- Wallet: `go test ./...` passes.
|
||||||
|
- GL: `go test ./...` passes (loopback test required the unrestricted runner).
|
||||||
|
- API health tests pass in an isolated verification copy populated with compatible generated stubs. The checkout itself still requires its normal `buf generate` build step because `domain/stub/go` is not committed.
|
||||||
|
|
||||||
|
Deployment prerequisite: the compose files still need the actual GL image/service definition and database secret. The config intentionally points to `gl:8600`; without that service, health is critical and mutations remain halted.
|
||||||
|
|
||||||
|
Remaining architectural limit: health preflight closes the known outage path but cannot make a GL write and Kuknos submission atomic. GL-first acknowledged reservation/command processing plus reconciliation is still required for a strict cross-system guarantee.
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Local Docker run
|
||||||
|
|
||||||
|
Date: 2026-08-29
|
||||||
|
|
||||||
|
- Runtime: Docker Desktop (`desktop-linux`), not OrbStack.
|
||||||
|
- Branch: `feat/refactor-v1` across project repositories.
|
||||||
|
- Registries: Go uses `https://go.reg.darano.ir`; Python/uv uses `https://pypi.reg.darano.ir/simple/`.
|
||||||
|
- Stack: all 14 roles are running, including GL, API, auth, wallet, market, internal-wallet, alert, streamer, cron, UI, AdminPanel, PostgreSQL, Redis, and RabbitMQ.
|
||||||
|
- Local URLs: UI `http://localhost:3001`, API `http://localhost:3000`, AdminPanel `http://localhost:8080`, RabbitMQ `http://localhost:15672`.
|
||||||
|
- Local Kuknos switch: `DARANO_KUKNOS_ENABLED=false`; GL remains mandatory. Remove/enable this override when Kuknos test Horizon is usable.
|
||||||
|
|
||||||
|
Verification:
|
||||||
|
|
||||||
|
- API health: `200 {"ready":true,"status":"ok"}`; UI: `200`; AdminPanel: expected locale redirect (`302`).
|
||||||
|
- GL outage test: stopping GL changed API health to HTTP 503 critical, halted outbox delivery, and emitted structured `financial_availability.changed` logs with `severity=CRITICAL`. Readiness recovered after GL restart.
|
||||||
|
- Tests passed: API config absolute-path test; wallet config and PostgreSQL repository suites.
|
||||||
|
|
||||||
|
Known non-blocking UI warnings: malformed `.eslintrc.json`, obsolete `fileExtensions` Next config option, and duplicate Buf-generated filename warnings.
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Darano assessment
|
||||||
|
|
||||||
|
Darano is a multi-service tokenization and trading platform centered on real-estate assets, with Mellat integration for fiat payments and Kuknos/Stellar for settlement. The recovered work adds a strong GL mirror and durable event infrastructure, but the requested target is not complete.
|
||||||
|
|
||||||
|
## Verdict
|
||||||
|
|
||||||
|
- Business domains are identifiable and documented in `02-business-domains.md`.
|
||||||
|
- A project index and mind map are complete.
|
||||||
|
- GL's feature branch is checked out, append-only, and its full tests pass. It is now started by the development Procfile and configured as `gl:8600`, but compose still needs a concrete GL service/image and database secret.
|
||||||
|
- GL is the primary append-only financial truth; Kuknos is secondary settlement/verification truth. The new shared gate enforces both in normal mode, always halts on GL failure, and permits only an explicit startup-time `kuknos-enabled=false` mode. It never switches automatically.
|
||||||
|
- User transactions are not uniformly event driven. The one-event-per-transaction design can publish a `CREATED` request too early and never re-enqueue it after confirmation; only four types have executable consumers.
|
||||||
|
- Wallet and GL full suites pass. Tests now cover fail-closed RPC admission and paused event claims, but not complete cross-system user lifecycles or the health-check/commit race.
|
||||||
|
|
||||||
|
## Recommended next slice
|
||||||
|
|
||||||
|
1. Fix the command/event lifecycle and add end-to-end tests for internal transfer first.
|
||||||
|
2. Replace monetary `float64` at service/persistence boundaries with fixed-point values.
|
||||||
|
3. Add the concrete GL compose deployment/database secret, then implement reconciliation.
|
||||||
|
4. Replace health-preflight-only coordination with GL-first acknowledged reservations/commands so GL and Kuknos cannot diverge across the check/submit race.
|
||||||
|
5. Move AdminPanel mutations behind internal service APIs.
|
||||||
|
|
||||||
|
## Staging limitation
|
||||||
|
|
||||||
|
Direct interactive access to `https://stage.darano.ir` was unavailable. The supplied staging screenshots confirm wallet totals/locks, market and ICO purchase screens, legal agreement acceptance, transaction history, verified Sheba accounts, IRT withdrawal, and referrals; these flows are captured in `04-product-flows.md`.
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# Darano mind map
|
||||||
|
|
||||||
|
```text
|
||||||
|
Darano tokenization platform
|
||||||
|
├── Customers and assets
|
||||||
|
│ ├── Mellat Bank: primary customer and IPG rail
|
||||||
|
│ ├── Real estate: principal real-world asset
|
||||||
|
│ └── Token publisher: authorized ICO inventory owner
|
||||||
|
├── Customer product
|
||||||
|
│ ├── Login, identity, TFA, bank information
|
||||||
|
│ ├── Projects and token discovery
|
||||||
|
│ ├── Wallets, balances, trustlines
|
||||||
|
│ ├── Buy, deposit, transfer, withdraw, redeem
|
||||||
|
│ ├── Marketplace orders and history
|
||||||
|
│ └── BNPL and referral commissions
|
||||||
|
├── Financial orchestration
|
||||||
|
│ ├── API gateway -> gRPC services
|
||||||
|
│ ├── Wallet/Market -> validation and settlement
|
||||||
|
│ ├── PostgreSQL -> operational state
|
||||||
|
│ ├── Redis -> locks/cache
|
||||||
|
│ └── RabbitMQ/Watermill -> transaction commands/events
|
||||||
|
├── Sources of truth
|
||||||
|
│ ├── GL -> primary append-only financial truth
|
||||||
|
│ ├── Immutable double-entry journals
|
||||||
|
│ ├── Transaction lifecycle events
|
||||||
|
│ ├── Available/frozen/clearing/treasury accounts
|
||||||
|
│ ├── Balance and journal explorer
|
||||||
|
│ ├── Mirror transport: implemented foundation
|
||||||
|
│ ├── Mandatory availability gate: missing
|
||||||
|
│ ├── Critical health plus OTel incident reporting: missing
|
||||||
|
│ └── Reconciliation: missing
|
||||||
|
│ └── Kuknos (Stellar compatible) -> secondary settlement truth
|
||||||
|
│ ├── Required together with GL in normal mode
|
||||||
|
│ └── Manual operator disable mode: missing
|
||||||
|
├── Operations
|
||||||
|
│ ├── Django AdminPanel
|
||||||
|
│ ├── Direct DB writes: current invariant bypass
|
||||||
|
│ ├── DevOps/Traefik/Compose
|
||||||
|
│ └── Monitoring and alerting
|
||||||
|
└── Main work remaining
|
||||||
|
├── Correct event command lifecycle
|
||||||
|
├── Fixed-point money end to end
|
||||||
|
├── GL fail-closed gate, startup/deployment, and reconciliation
|
||||||
|
├── Trustline and reserved-balance GL model
|
||||||
|
├── Critical health and OpenTelemetry incident reporting
|
||||||
|
└── End-to-end domain/outage tests
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user