Compare commits

..

123 Commits

Author SHA1 Message Date
nfel 843103429b docs(refactor): complete api architecture phase 2026-08-31 23:46:45 +03:30
nfel 77e2f4d874 docs(refactor): complete wallet phase tracker 2026-08-31 16:18:58 +03:30
nfel cc1ed9a178 docs: update cross-machine continuation memory 2026-08-30 23:05:02 +03:30
nfel 478d23acc9 docs: record configurable cron schedule 2026-08-30 21:00:10 +03:30
nfel 7d2a442309 docs: record cron logging cleanup 2026-08-30 20:59:16 +03:30
nfel 57bccd9fe6 docs: record lock response contract 2026-08-30 20:58:44 +03:30
nfel 224d867d4a docs: record lock request validation 2026-08-30 20:45:30 +03:30
nfel 37919982cd docs: record transaction boundary hardening 2026-08-30 20:44:49 +03:30
nfel 019021af06 docs: record wallet init commit handling 2026-08-30 20:43:47 +03:30
nfel 2c3c294362 docs: record agreement id cleanup 2026-08-30 20:42:42 +03:30
nfel 7ce552e074 docs: record contract rounding cleanup 2026-08-30 20:40:56 +03:30
nfel 4e1e0c9d31 docs: record redeem allocation cleanup 2026-08-30 20:38:55 +03:30
nfel 7c0b8b6389 docs: record referral policy cleanup 2026-08-30 20:36:02 +03:30
nfel 95488f9772 docs: record discount policy extraction 2026-08-30 20:34:54 +03:30
nfel 4142e9221a docs: record payer ID shim cleanup 2026-08-30 20:33:50 +03:30
nfel e4ceb44f8c docs: record IPG amount shim cleanup 2026-08-30 20:33:04 +03:30
nfel 24b1c96cab docs: record market agreement shim cleanup 2026-08-30 20:32:09 +03:30
nfel db4e15b507 docs: start W012 shim cleanup 2026-08-30 20:19:43 +03:30
nfel 5dbaa1df7c docs: complete named wallet setup paths 2026-08-30 20:18:42 +03:30
nfel 84f5602e3f docs: record internal wallet bootstrap isolation 2026-08-30 20:17:53 +03:30
nfel 557a30d959 docs: record market bootstrap isolation 2026-08-30 20:17:04 +03:30
nfel 6cb705ffcb docs: start W011 explicit composition 2026-08-30 20:16:12 +03:30
nfel f21c0933b0 docs: record stream bootstrap separation 2026-08-30 20:15:11 +03:30
nfel ffb0815238 docs: start W009 internal wallet extraction 2026-08-30 20:05:39 +03:30
nfel f613f010af docs: record alert IAM validation 2026-08-30 20:04:16 +03:30
nfel 3ab120aa0e docs: record alert nil-event guard 2026-08-30 20:03:21 +03:30
nfel c29fbda989 docs: record market settlement lock fix 2026-08-30 20:02:28 +03:30
nfel 45170dd1e6 docs: record stream deposit policy 2026-08-30 20:01:34 +03:30
nfel 4cf68072e1 docs: record cron bootstrap isolation 2026-08-30 20:00:24 +03:30
nfel 8dfe713afb docs: record W010 stream lookup policy 2026-08-30 19:59:18 +03:30
nfel 1b66c3c4cd docs: start W010 cron extraction 2026-08-30 19:58:12 +03:30
nfel 527e138b83 docs: record deterministic transaction lock ordering 2026-08-30 19:57:11 +03:30
nfel 2ac7731c52 docs: record W008 alert subject policy 2026-08-30 19:55:36 +03:30
nfel 6b875fbd16 docs: start W008 alert extraction 2026-08-30 19:54:33 +03:30
nfel 1e04b08ff4 docs: record W007 ICO publisher policy 2026-08-30 19:53:16 +03:30
nfel 594c7a0301 docs: record W007 order status policy 2026-08-30 19:52:16 +03:30
nfel 03a17e9f29 docs: record W007 order input policy 2026-08-30 19:51:09 +03:30
nfel 54ad72c477 docs: record W007 pricing extraction 2026-08-30 19:50:10 +03:30
nfel 131fa6e6d3 docs: record W007 raw amount policy 2026-08-30 19:48:15 +03:30
nfel 7ab01f9580 docs: record W007 market availability policy 2026-08-30 19:47:16 +03:30
nfel 89697d0528 docs: start W007 market extraction 2026-08-30 19:46:19 +03:30
nfel a5a19cae62 docs: record W006 failure policy extraction 2026-08-30 19:44:40 +03:30
nfel ec608a8909 docs: record W006 balance policy extraction 2026-08-30 19:43:46 +03:30
nfel df6436b512 docs: clarify W006 outbox and idempotency status 2026-08-30 19:42:52 +03:30
nfel fcdffd247c docs: record W006 redeem completion policy 2026-08-30 19:41:59 +03:30
nfel 9bf20be350 docs: record W006 redeem transaction policy 2026-08-30 19:40:57 +03:30
nfel 0b942360b7 docs: record W006 successful deposit policy 2026-08-30 19:39:59 +03:30
nfel 07cfe5a73e docs: record W006 devmode update policy 2026-08-30 19:38:52 +03:30
nfel 96c2e34a04 docs: record W006 settlement update policy 2026-08-30 19:38:03 +03:30
nfel e22d097b92 docs: record W006 successful transaction policy 2026-08-30 19:37:05 +03:30
nfel e11ca3476d docs: record W006 IRT deposit policy routing 2026-08-30 19:35:35 +03:30
nfel d6e19a59b1 docs: record W006 transfer transaction extraction 2026-08-30 19:34:23 +03:30
nfel 1fa6beedb9 docs: record deposit withdrawal transaction extraction 2026-08-30 19:31:57 +03:30
nfel 01aef1b3ae docs: record IPG payer policy extraction 2026-08-30 19:30:28 +03:30
nfel 7da464ea0c docs: record transaction event policy extraction 2026-08-30 19:28:57 +03:30
nfel ff0842906f docs: record transaction status extraction 2026-08-30 19:28:00 +03:30
nfel 57defd5686 docs: record settled deposit extraction 2026-08-30 19:27:07 +03:30
nfel f5a9d9a06a docs: record transfer policy extraction 2026-08-30 19:25:44 +03:30
nfel 0c0d677a82 docs: record deposit policy extraction 2026-08-30 19:24:47 +03:30
nfel 7f58c31d6b docs: start wallet transaction extraction 2026-08-30 19:23:43 +03:30
nfel 44cf2f131e docs: complete federation removal task 2026-08-30 19:22:14 +03:30
nfel 1bcab31ad7 docs: record federation removal progress 2026-08-30 19:16:25 +03:30
nfel ae90ebed3a docs: add federation removal investigation tasks 2026-08-30 19:12:21 +03:30
nfel 3b61787a62 docs: record wallet orchestration coverage 2026-08-30 19:08:39 +03:30
nfel 3ace94df91 docs: record initialization transaction coverage 2026-08-30 19:07:42 +03:30
nfel fa2eec96f9 docs: record wallet initialization rollback policy 2026-08-30 19:06:38 +03:30
nfel 48d6931c68 docs: record trustline transaction extraction 2026-08-30 19:05:49 +03:30
nfel 7e8664c577 docs: record wallet creation orchestration extraction 2026-08-30 19:04:46 +03:30
nfel 3c16ff0ca2 docs: record wallet draft extraction 2026-08-30 19:02:50 +03:30
nfel 2ecaf7f242 docs: record wallet creation policy extraction 2026-08-30 19:01:58 +03:30
nfel dd6de15d8c docs: record trustline adapter extraction 2026-08-30 19:00:39 +03:30
nfel 13669ecef3 docs: checkpoint wallet initialization extraction 2026-08-30 18:59:03 +03:30
nfel 23852b00c3 docs: complete wallet read use case extraction 2026-08-30 18:57:38 +03:30
nfel 9b120daae0 docs: record transaction read extraction 2026-08-30 18:56:08 +03:30
nfel a60fe1fa4a docs: update wallet read extraction checkpoint 2026-08-30 18:54:45 +03:30
nfel eda8130671 docs: record wallet read boundary progress 2026-08-30 18:53:34 +03:30
nfel 09ca346abe docs: checkpoint wallet read use cases 2026-08-30 18:52:36 +03:30
nfel 9ac0473138 docs: complete wallet infrastructure adapter migration 2026-08-30 18:49:36 +03:30
nfel ba14f6cfdb docs: record wallet infrastructure migration checkpoint 2026-08-30 18:44:12 +03:30
nfel e2646ee70e docs: complete wallet domain foundation 2026-08-30 18:40:51 +03:30
nfel 9b68152bd0 docs: map wallet runtime dependencies 2026-08-30 18:35:57 +03:30
nfel 0f12a7e2bb docs: complete auth persistence migration 2026-08-30 18:32:04 +03:30
nfel c998469b3a docs: complete auth compatibility cleanup 2026-08-30 18:23:05 +03:30
nfel 37722738aa docs: complete auth composition task 2026-08-30 18:20:04 +03:30
nfel 3f1d83e2e7 docs: complete identity permission task 2026-08-30 18:18:32 +03:30
nfel 1723e9dc8d docs: record identity validation extraction 2026-08-30 18:17:13 +03:30
nfel 02adb54f61 docs: record identity store wiring 2026-08-30 18:15:11 +03:30
nfel 820da91c77 docs: record role permission reader extraction 2026-08-30 18:09:41 +03:30
nfel c083d042c1 docs: record permission repository wiring 2026-08-30 18:05:38 +03:30
nfel fd72713d98 docs: start identity permission extraction 2026-08-30 18:03:58 +03:30
nfel 7dcb9f58f1 docs: complete authentication JWT task 2026-08-30 18:02:44 +03:30
nfel 0c4d809316 docs: record auth session write migration 2026-08-30 18:01:37 +03:30
nfel 850177b60c docs: record auth session store wiring 2026-08-30 18:00:39 +03:30
nfel 048a53644e docs: record session validation policy 2026-08-30 17:58:38 +03:30
nfel 3b1c61bae2 docs: record JWT verifier injection 2026-08-30 15:36:08 +03:30
nfel a4a389e5c3 docs: record JWT verifier boundary 2026-08-30 15:34:31 +03:30
nfel 542512c0c5 docs: record refresh token policy extraction 2026-08-30 15:33:44 +03:30
nfel ebd4788e13 docs: start authentication JWT task 2026-08-30 15:33:06 +03:30
nfel 9cf842980a docs: complete OTP extraction task 2026-08-30 15:25:37 +03:30
nfel b7eff051da docs: record OTP template wiring 2026-08-30 15:24:42 +03:30
nfel 372f090c80 docs: record OTP runtime wiring 2026-08-30 15:23:31 +03:30
nfel 6d68a423c3 docs: record OTP infrastructure adapters 2026-08-30 15:07:47 +03:30
nfel 987559f370 docs: record OTP application ports checkpoint 2026-08-30 15:06:53 +03:30
nfel d4a09445c7 docs: record OTP verification checkpoint 2026-08-30 15:02:33 +03:30
nfel 56d8123f44 docs: record OTP template parsing checkpoint 2026-08-30 14:58:32 +03:30
nfel f10dd3f950 docs: record OTP application checkpoint 2026-08-30 14:57:01 +03:30
nfel ce0cb481bc docs: record remaining auth persistence adapters 2026-08-30 14:55:51 +03:30
nfel 491a0cf26e docs(auth): record domain adapter checkpoint 2026-08-30 14:52:15 +03:30
nfel 1ba8c79a11 docs(auth): record infrastructure adapter boundary 2026-08-30 14:50:10 +03:30
nfel 88a0307c4a docs(auth): track persistence migration checkpoint 2026-08-30 14:49:16 +03:30
nfel 5d9c2fa33b docs(auth): include domain error checkpoint 2026-08-30 14:47:20 +03:30
nfel 10affbc629 docs(auth): record domain foundation checkpoint 2026-08-30 14:46:47 +03:30
nfel bc5c8c4950 docs(auth): map RPC dependencies for architecture migration 2026-08-30 14:44:13 +03:30
nfel 2f5db4a667 docs(auth): record periodic identity validation 2026-08-30 14:43:35 +03:30
nfel fa0251f5b2 docs(refactor): complete GL tasks 2026-08-30 14:30:44 +03:30
nfel fad5f5b7f3 docs(refactor): complete API config tasks 2026-08-30 14:26:02 +03:30
nfel e8996427bd docs(refactor): complete wallet config injection 2026-08-30 12:37:49 +03:30
nfel c40c9ea517 Procfile must use pnpm instead of yarn 2026-08-29 11:25:42 +03:30
Navid 227bed27b8 docs: report local Docker verification 2026-08-29 10:02:40 +03:30
Navid 8e634d5739 docs: capture refactor workflow and project memory 2026-08-29 09:57:58 +03:30
nfel 8bff15a0ad docs: use SSH for workspace handoff 2026-08-28 15:13:18 +03:30
nfel 3d5f8e68f9 docs: add workspace clone commands 2026-08-28 14:59:42 +03:30
nfel 01d3780a77 docs: centralize refactoring coordination files 2026-08-28 14:49:42 +03:30
18 changed files with 2611 additions and 1 deletions
+221
View File
@@ -0,0 +1,221 @@
# AGENTS.md
This file provides guidance for agents working in the Darano monorepo.
## Repository Structure
Multi-service monorepo for the Darano financial/crypto platform. Each subdirectory is its own independent git repository:
| Directory | Language | Role |
|-----------|----------|------|
| `api/` | Go (Gin) | HTTP REST gateway — the only public-facing service |
| `auth/` | Go (gRPC) | Authorization — OTP, JWT, permissions, identity |
| `wallet/` | Go (gRPC) | Wallet — assets, transactions, Stellar blockchain, market |
| `ui/` | TypeScript/Next.js | Customer-facing frontend |
| `AdminPanel/` | Python/Django | Internal admin panel (bypasses api, hits Postgres directly) |
| `proto/` | Protobuf | Central schema definitions shared by all services |
| `DevOps/` | Docker Compose | Infrastructure — Postgres, Redis, RabbitMQ, MinIO, Traefik |
| `docs/` | MkDocs | Documentation site |
**Root-level**: `Procfile` (deployment), `CLAUDE.md` (Claude Code config) — these are the monorepo's coordination files, not service-level.
## Service Communication Architecture
```
Browser/Client → api (REST/HTTP) → auth, wallet/market/alert (gRPC)
AdminPanel ──────────────────────→ Postgres directly (bypasses api)
```
The `api` gateway is the **only** HTTP-facing service. All inter-service communication is gRPC.
### API Gateway (api/)
- **Entry/composition**: `api/main.go``cmd.Execute()` (Cobra) → `cmd/apiRuntime`, which explicitly owns clients, handlers, router, HTTP servers, permission synchronization, and cleanup.
- **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/interface/http/handler/` — one file per domain. Handlers depend on `application/port.Upstreams`.
- **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
- **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
### Wallet Binary (wallet/)
Single binary hosts multiple sub-services via Cobra subcommands: `wallet`, `market`, `alert`, `internal_wallet`, `stream`. These are spawned concurrently via `errgroup` in `cmd/cmdServe/main.go`.
**Concurrent build safety**: The Makefile uses `flock` on `./.build/air-build.lock` to serialize protobuf generation and binary writes when multiple air instances run simultaneously (`make dev-wallet`, `make dev-market`, etc. all trigger `make build`).
### Config
- **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
- **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)
### Config files reference
| Service | Config file |
|---------|------------|
| API | `./cfg.toml` (or `--conf ./config.cfg`) |
| Wallet sub-services | `./wallet.cfg.toml`, `./market.cfg.toml`, `./alert.cfg.toml`, `./stream.cfg.toml` |
| Internal wallet | `./wallet.internal.cfg.toml` |
## Commands
### Go services (`api/`, `auth/`)
```bash
cd api/ # or cd auth/
make dep # install buf, protoc plugins, swag, air
make build # fmt + proto gen + binary → ./build/main
make dev # build + hot reload via air
make test # go test ./...
./build/main serve --conf ./cfg.toml
```
### Wallet service (`wallet/`)
```bash
cd wallet/
make build # proto gen + binary
make dev-wallet # hot reload wallet sub-service (.wallet.air.toml)
make dev-market # hot reload market sub-service (.market.air.toml)
make dev-stream # hot reload stream sub-service (.stream.air.toml)
make run-wallet # ./build/main serve wallet -c ./wallet.cfg.toml
make run-market # ./build/main serve market -c ./market.cfg.toml
make run-internal # ./build/main serve internal_wallet -c ./wallet.internal.cfg.toml
make run-alert # ./build/main serve alert -c ./alert.cfg.toml
make run-stream # ./build/main stream -c ./stream.cfg.toml
make grpc-ui-wallet # open grpcui on port 7210 (localhost:8200)
make grpc-ui-market # open grpcui on port 7300 (localhost:8300)
make grpc-ui-alert # open grpcui on port 7400 (127.0.0.1:8400)
```
**Important**: When running multiple sub-services concurrently via `make run` or multiple `make dev-*` instances, the Makefile uses `flock` to prevent concurrent protobuf generation or binary overwrites. Don't parallelize make (`-j`) without `flock` — it will corrupt stub files.
### AdminPanel (`AdminPanel/`)
```bash
cd AdminPanel/
# DB setup (uv virtual env)
uv run python src/manage.py makemigrations
uv run python src/manage.py migrate
make run # runserver on 0.0.0.0:8080
make dev # watch mode using funzzy
make proto # buf generate → proto stubs via betterproto
make build-msg # compile Django messages (i18n)
```
### UI (`ui/`)
```bash
cd ui/
yarn build-proto # generate TS types from protos (buf generate)
yarn dev # Next.js dev server (also runs buf generate)
make dev # same, bound to 0.0.0.0:3000
yarn lint # ESLint
yarn lint:fix # ESLint with auto-fix
yarn build # production build (also runs buf generate)
```
## Protobuf Code Generation
All services depend on generated code. **Always run `make build-proto` (or `yarn build-proto` for UI) before building any service.**
Proto definitions live in `proto/` with subdirectories: `base/`, `auth/`, `wallet/`, `market/`, `alert/`, `errors/`. Each service has its own `buf.gen.yaml` controlling code generation output into `domain/stub/go/` (Go) or `src/types/stub/` (TypeScript).
**Gotcha**: The Go Makefiles **strip `omitempty`** from all JSON struct tags in `.pb.go` files after generation. This is intentional — protobuf JSON serialization needs consistent field presence. Do not re-add `omitempty` manually.
## Go Service Layer Pattern
Both `auth` and `wallet` follow a layered architecture:
- **`config/`** — TOML config via koanf. `config.Cfg` global singleton, `sync.Once` initialized.
- **`domain/stub/go/`** — Generated protobuf Go code. **Never edit manually.**
- **`cmd/`** — Cobra CLI entry points. Subcommands map to serve modes.
- **`repository/`** — Data access. Aggregates `IPostgres`, `IRedis`, `IService`, and `IQueue` (wallet only) interfaces.
- **`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 `wallet`, `core/` contains sub-packages: `walletImp/`, `marketImp/`, `alertImp/`, `cronJobs/`.
## API Gateway Patterns
### Request/Response Flow
```
HTTP request → interface/http middleware → interface/http/handler → application Upstreams port → infrastructure/grpcclient → backend service
```
- **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**: `interface/http/handler/contextWithMetadata()` copies HTTP headers into incoming and outgoing gRPC metadata.
- **Handler interface**: `interface/http/handler.Server` receives the `application/port.Upstreams` boundary and configuration explicitly.
### Route conventions
- Public routes: `/v1/public/{domain}/{action}` — no JWT needed
- Client routes: `/v1/client/{domain}/{action}` — JWT required (validated by `AuthorizationMiddleware`)
- Admin routes: `/v1/admin/{domain}/{action}` — JWT required (mostly placeholder currently)
## UI Architecture
- **Next.js App Router** under `src/app/`. Notable route groups: `dashboard/` (auth-protected), `auth/login/`, `blog/` (MDX content), `projects/`, `receipt/`.
- **Auth**: `src/middleware.ts` uses next-auth to protect `/dashboard/:path*`. Exports default from `next-auth/middleware`.
- **Services**: `src/services/` — plain functions wrapping axios calls to the api gateway, typed with generated protobuf types.
- **State**: `src/stores/` — Zustand stores.
- **Hooks**: `src/hooks/` — TanStack Query hooks on top of service functions.
- **Components**: HeroUI + Tailwind CSS with RTL support (Persian/Farsi UI).
- **Forms**: Formik + Yup (older), react-hook-form (newer).
- **Date picker**: `@amir04lm26/react-modern-calendar-date-picker` (Jalali calendar).
- **MDX**: Blog content uses `.mdx` files with remark/rehype plugins.
- **Path alias**: `@/*` maps to `./src/*`.
- **Output**: `standalone` mode for Docker. Image domains hardcoded in `next.config.mjs` remote patterns.
## Infrastructure
Dev infrastructure: `DevOps/dev/compose.yml` — PostgreSQL 16, Redis, RabbitMQ, MinIO. Each Go service has its own DB name.
All Go services instrumented with Elastic APM and Prometheus metrics. Traefik handles TLS/routing in production.
## Gotchas and Non-Obvious Details
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 RPC. Active calls prevent idle closure; peers close after the configured inactivity timeout (2-minute default) and reconnect on the next call.
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 `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.
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/`.
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`).
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.
## 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`.
- **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.
- **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.
- **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.
- `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 router has a typo: `no_migartion` → should be `no_migration`.
- 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
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, 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.
**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.
**Migration phases** (see plan for details): Config standardization → auth/ restructure → wallet/ restructure → api/ restructure → AdminPanel service layer → shared domain types. Parallel workstreams: Go services restructure can run alongside AdminPanel gRPC client creation.
+112
View File
@@ -0,0 +1,112 @@
# 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 W005W012 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.
### 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.
+2 -1
View File
@@ -1,6 +1,7 @@
# Go services — air builds on first run and rebuilds+restarts on any .go change
api: cd api && sleep 2 && air
auth: cd auth && air
gl: cd GL && air
# 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.
@@ -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
# 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
docs: cd docs && make dev
+420
View File
@@ -0,0 +1,420 @@
# Wallet, Authentication, and API Refactoring Guide
This document records the current architectural and correctness risks in Darano's wallet, authentication, and API services, and proposes a safe sequence for refactoring them.
The recommended approach is an evolutionary refactor rather than a simultaneous rewrite. First stabilize financial and authentication flows, then establish explicit contracts and an append-only ledger, and finally migrate individual operations behind the new boundaries.
The existing [Spring 1404 technical report](docs/docs/%DA%AF%D8%B2%D8%A7%D8%B1%D8%B4%20%D9%87%D8%A7/%DA%AF%D8%B2%D8%A7%D8%B1%D8%B4-%D8%A8%D9%87%D8%A7%D8%B1-%DB%B1%DB%B4%DB%B0%DB%B4.md) is directionally correct about introducing an internal ledger. Its proposed schema should be extended with accounting invariants, reservations, idempotency, reversals, and reconciliation before implementation.
## Executive recommendation
Do not split the system into more independently deployed services yet. Keep the wallet as a modular service while the financial invariants are established. Prematurely separating ledger, market, settlement, and blockchain concerns would introduce more distributed failure modes without fixing the current consistency problems.
The first architectural decision must be the authoritative source of balances:
1. **Recommended:** an internal double-entry ledger is authoritative for available and reserved balances; Stellar is the custody and settlement layer.
2. **Alternative:** Stellar remains authoritative and PostgreSQL is a read-only projection.
The current system mixes both approaches: wallet reads retrieve Stellar balances and write them back to PostgreSQL, while other flows mutate PostgreSQL balances directly. This ambiguity must be removed.
## Highest-risk findings
### 1. Financial operations are not safely repeatable
- Asset purchase returns success before execution completes. Work runs in an in-process goroutine, so a restart can lose the operation. The accepted-agreement condition also does not reject a normally accepted agreement: [`wallet/core/walletImp/buy.go`](wallet/core/walletImp/buy.go#L390).
- The payment callback has no atomic terminal-state transition. A replay can repeat settlement and potentially initiate another on-chain credit, depending on provider behavior: [`wallet/core/walletImp/ipg.go`](wallet/core/walletImp/ipg.go#L131).
- Transfer confirmation loads a transaction using a caller-supplied ID without validating its owner, original asset, amount, recipient, type, or current state: [`wallet/core/walletImp/transfer.go`](wallet/core/walletImp/transfer.go#L208).
- IRT withdrawal confirmation has the same ownership and state-binding problem: [`wallet/core/walletImp/irt.go`](wallet/core/walletImp/irt.go#L110).
- `DepositIRT` creates a pending transaction and then calls another function that creates a second transaction: [`wallet/core/walletImp/irt.go`](wallet/core/walletImp/irt.go#L192).
Every financial command must accept an idempotency key, bind approval or MFA to the exact immutable transaction intent, and use a compare-and-set state transition.
### 2. The blockchain streamer has broken duplicate handling
The normal `record not found` result returns before inserting a deposit. That return also occurs before the mutex unlock is deferred, leaving the lock held until its TTL expires: [`wallet/port/stellar/stream.go`](wallet/port/stellar/stream.go#L91).
The streamer also needs a persistent blockchain cursor, a unique constraint on the external operation identity, replay-safe ingestion, and reconciliation against missed operations.
### 3. Database errors can be silently converted into success
The transaction helper wraps the named `err`, which is still nil, rather than `result.Error`: [`wallet/repository/db/postgres/tx.go`](wallet/repository/db/postgres/tx.go#L10).
Similar mistakes exist in transaction processing, including wallet fetch and commit failures: [`wallet/core/walletImp/transaction.go`](wallet/core/walletImp/transaction.go#L172).
Errors from `Begin`, `Commit`, `Rollback`, row-count checks, Redis, queues, and provider calls must never be ignored. Financial state transitions should fail closed.
### 4. Balance authority is ambiguous
Wallet reads query Stellar, merge blockchain and database state, calculate locks, and then update database balances as a side effect of reading: [`wallet/core/walletImp/wallet.go`](wallet/core/walletImp/wallet.go#L335).
Other paths directly mutate database balances. A refactor must define one authority, make projections explicitly disposable and rebuildable, and continuously reconcile the authority against custody and settlement systems.
### 5. Financial amounts use binary floating point
PostgreSQL `NUMERIC` values are represented as Go `float64` for wallet balances and transaction amounts:
- [`wallet/domain/db/wallet.go`](wallet/domain/db/wallet.go#L19)
- [`wallet/domain/db/transaction.go`](wallet/domain/db/transaction.go#L35)
Use integer minor units where the asset permits it, or an exact decimal type with an explicit scale per asset. Rounding rules must be named, centralized, and tested at every external boundary.
### 6. Concurrency protection is insufficient
- Balance reads inside database transactions do not lock rows using `SELECT ... FOR UPDATE` or an equivalent atomic update.
- The custom Redis lock is a non-atomic GET followed by SET, ignores Redis failures, and has no ownership token: [`wallet/repository/lock.go`](wallet/repository/lock.go#L13).
- Stellar sequence-number locking is commented out: [`wallet/port/stellar/transfer.go`](wallet/port/stellar/transfer.go#L130).
- Important uniqueness constraints are absent, including one wallet per `(user_id, asset_id)` and one accounting record per user.
Prefer database invariants and atomic conditional updates over distributed locks. When a distributed lock is unavoidable, it must use an owner token, safe release, bounded lease renewal, and fencing where applicable.
### 7. Migration and database transport policies are unsafe
Auth and wallet run GORM `AutoMigrate` during service startup. Wallet also disables PostgreSQL TLS and GORM's default transaction behavior: [`wallet/repository/db/postgres/main.go`](wallet/repository/db/postgres/main.go#L21).
Replace runtime migration with reviewed, versioned migrations. Use expand/contract deployments, migration tests, explicit rollback or forward-fix procedures, and TLS outside local development.
### 8. Internal gRPC trusts caller-supplied identity
Wallet RPC messages contain `InternalIAM`, but the wallet gRPC server does not install an authentication or authorization interceptor: [`wallet/cmd/cmdServe/wallet.go`](wallet/cmd/cmdServe/wallet.go#L74).
Service clients use plaintext `grpc.WithInsecure()`: [`api/service/main.go`](api/service/main.go#L107).
Any peer able to reach the gRPC ports may be able to forge an IAM payload. Internal communication should use:
- mTLS with service identities;
- per-RPC service authorization;
- a signed, short-lived user principal in metadata;
- network policies that make internal RPCs unreachable from the public edge;
- server-side derivation of identity instead of trusting protobuf body fields.
### 9. Authentication sessions and OTP need redesign
- OTP generation uses `math/rand`; development mode uses a fixed code: [`auth/usecase/tfa.go`](auth/usecase/tfa.go#L51).
- Failed OTP attempts rewrite the Redis entry with a 24-hour TTL: [`auth/repository/otp.go`](auth/repository/otp.go#L54).
- No per-mobile, IP, device, ASN, or system-wide OTP rate limiting is visible.
- Refresh-token rotation is not atomic. Concurrent reuse can mint multiple valid access tokens: [`auth/usecase/authorization.go`](auth/usecase/authorization.go#L221).
- JWT verification validates audience but does not explicitly constrain issuer and permitted algorithms. Signing keys are reread for each request, and no `kid`/JWKS rotation model exists: [`auth/util/auth.go`](auth/util/auth.go#L18).
- Permission checks are bypassed outside production. API routes are converted into permissions at startup, and newly created system roles are assigned to every user: [`auth/usecase/permission.go`](auth/usecase/permission.go#L57).
- Login synchronously calls wallet to provision a public key, coupling auth availability to wallet availability: [`auth/usecase/authorization.go`](auth/usecase/authorization.go#L166).
Auth should implement refresh-token families with hashed tokens, atomic rotation and replay detection, logout and revoke-all, device metadata, key rotation, secure OTP generation, abuse controls, and static deny-by-default policy definitions.
Wallet provisioning should be lazy or triggered by a durable `UserKYCVerified` event instead of blocking login.
### 10. API edge protections are incomplete
- Request and response logging can capture OTPs, access tokens, refresh tokens, banking data, and other PII: [`api/middlewares/logger.go`](api/middlewares/logger.go#L13).
- APM attaches national ID and mobile to traces.
- Gin uses its default HTTP server without explicit read, write, header, idle, and shutdown timeouts or request body limits: [`api/cmd/serve.go`](api/cmd/serve.go#L82).
- Metrics, Swagger, and WebSocket endpoints are registered on the public router without visible endpoint-specific protection.
- Multiple CORS origins are joined into one invalid response header: [`api/middlewares/cors.go`](api/middlewares/cors.go#L11).
- gRPC connections are deliberately closed after two minutes while generated clients keep references to the closed connection: [`api/service/main.go`](api/service/main.go#L128).
The API gateway should enforce request size and time limits, rate limits, security headers, redaction, idempotency, strict validation, bounded downstream deadlines, and a consistent public error model.
### 11. Key custody has a large compromise radius
The wallet configuration contains the master key and server secret keys, and user private keys are derived inside the wallet process from the master key and national ID:
- [`wallet/config/config.go`](wallet/config/config.go#L74)
- [`wallet/port/stellar/recoverKey.go`](wallet/port/stellar/recoverKey.go#L36)
Compromise of the wallet process or its configuration can therefore expose every derived user key. Define a custody model using an HSM, KMS, or isolated signing service; key versioning and rotation; hot/cold separation; quorum or maker-checker rules for high-value operations; backup and recovery; and an incident response procedure.
### 12. AdminPanel is a hidden wallet and auth consumer
AdminPanel reads unmanaged wallet and auth tables and directly modifies transaction status from a Django signal: [`AdminPanel/src/coreLogic/signals.py`](AdminPanel/src/coreLogic/signals.py#L14).
Schema and state-machine changes cannot safely proceed until AdminPanel is included in the migration plan. Prefer an authenticated internal command API for mutations and a dedicated read model for reporting.
### 13. Protobuf contracts and builds are not reproducible
API and auth generate protobufs from a moving `v2` branch, while wallet references an absolute path from another development machine:
- [`api/buf.gen.yaml`](api/buf.gen.yaml#L18)
- [`auth/buf.gen.yaml`](auth/buf.gen.yaml#L18)
- [`wallet/buf.gen.yaml`](wallet/buf.gen.yaml#L18)
Use one versioned protobuf module pinned to an immutable commit or release. Add Buf lint and breaking-change checks on every pull request, generate all clients from the same contract version, and publish deprecation metadata.
### 14. Test and CI coverage is effectively absent
The only Go test found is empty: [`wallet/repository/db/redis/lock_test.go`](wallet/repository/db/redis/lock_test.go#L9).
The service CI workflows build and deploy images without explicit unit tests, integration tests, race detection, vet, lint, migration checks, or contract compatibility checks: [`api/.gitea/workflows/ci.yaml`](api/.gitea/workflows/ci.yaml#L27).
The test strategy must be built before changing financial behavior.
## Recommended target boundaries
| Component | Responsibility |
| --- | --- |
| API gateway | HTTP validation, rate limits, idempotency, principal propagation, error mapping, and API compatibility. It should contain no financial logic or permission migrations. |
| Auth | Users, KYC, OTP/MFA, sessions, token issuance and revocation, and static policies. |
| Wallet core | Wallet commands, double-entry ledger, reservations, transaction state machines, and balance queries. |
| Payment orchestration | PSP callbacks, settlement, refunds, reversals, and reconciliation. |
| Chain adapter | Stellar-specific signing, submission, sequence management, confirmation, and chain reconciliation. |
| Workers | Durable processing of outbox records, callbacks, notifications, and retryable external work. |
| Admin | Authenticated internal command APIs and read-only reporting projections; no direct writes to core tables. |
Inside wallet, start with explicit modules rather than new services:
```text
wallet/
ledger/ append-only journals, entries, balances, holds
application/ commands and transaction state machines
payments/ IPG and bank orchestration
settlement/ chain intents and confirmation
chain/stellar/ Stellar adapter and signing client
reconciliation/ PSP, custody, supply, and ledger comparisons
projections/ user and admin read models
```
## Ledger requirements
The ledger must be append-only. Completed financial records should never be rewritten to represent a correction; use explicit reversal transactions.
At minimum, model:
- accounts scoped by owner, asset, purpose, and custody location;
- journals with a unique business operation and idempotency key;
- entries using exact amounts and explicit debit/credit direction;
- reservations or holds with purpose, status, and expiration;
- transaction state history;
- external settlement attempts and provider identifiers;
- outbox events committed in the same PostgreSQL transaction;
- optional materialized balance projections rebuildable from entries.
Required database invariants include:
- entries for each completed journal balance to zero per asset;
- every account has one asset and one defined scale;
- business and provider idempotency keys are unique;
- external blockchain hashes and PSP references are unique when present;
- state transitions use compare-and-set semantics;
- available balance cannot be overspent;
- immutable journal and entry rows cannot be updated or deleted by application roles.
## Transaction state machines
External operations cannot be made atomic with PostgreSQL. Model them as durable state machines or sagas.
An example withdrawal lifecycle is:
```text
requested
-> authorized
-> funds_reserved
-> signing
-> submitted
-> confirmed
-> completed
```
It must also support explicit failure states:
```text
expired
rejected
submission_unknown
failed
reversal_pending
reversed
manual_review
```
Each transition must record who or what initiated it, its timestamp, the previous state, an idempotency key, external references, and an auditable reason. Retries must resume from persisted state rather than restart the operation.
MFA approval should be bound to a hash of the exact intent, including user, operation type, asset, amount, recipient, fee, expiry, and nonce. An OTP tied only to a generic reason or record ID is insufficient.
## Refactoring sequence
### Phase 0: Stabilize and measure
- Freeze nonessential changes to financial flows.
- Patch the buy, callback, transfer, withdrawal, streamer, and transaction-error issues.
- Stop logging secrets and PII.
- Add missing uniqueness and positive-amount constraints after checking production data.
- Add correlation and idempotency IDs.
- Record metrics for transaction states, duplicates, balance drift, callback replay, OTP abuse, and chain lag.
### Phase 1: Add characterization tests
Before changing behavior, cover:
- OTP issuance, retry, expiry, and rate limiting;
- login, refresh rotation, concurrent refresh, logout, and revocation;
- internal and external transfers;
- IRT deposit, callback replay, settlement failure, and withdrawal;
- buy retries, compensation, and service restart;
- streamer restart, duplicate operations, cursor recovery, and missed events;
- wallet creation concurrency;
- AdminPanel mutations that currently affect wallet and auth state.
Add property tests for ledger invariants and concurrency tests for overspending and duplicate callbacks.
### Phase 2: Make contracts reproducible
- Pin protobuf inputs and generator versions.
- Add Buf lint and breaking checks.
- Define one structured error model using gRPC status details and a stable HTTP mapping.
- Add schema-level validation rules.
- Define pagination, filtering, public IDs, idempotency headers, and API deprecation rules.
- Generate and test UI clients from the same release.
### Phase 3: Secure service boundaries
- Add mTLS and service identities.
- Add gRPC authentication, authorization, deadline, recovery, metrics, and tracing interceptors.
- Remove caller-controlled IAM bodies.
- Restrict internal services using network policies.
- Replace manual connection expiry with normal long-lived gRPC connections and backoff.
- Move keys and provider credentials to managed secret storage.
### Phase 4: Refactor auth independently
- Introduce refresh-token families and store only token hashes.
- Rotate refresh tokens atomically and detect reuse.
- Support logout, revoke-all, device sessions, and administrative revocation.
- Validate issuer, audience, token type, timestamps, and permitted algorithms.
- Support `kid`-based signing-key rotation and JWKS distribution.
- Use cryptographically secure OTP generation and store OTP hashes.
- Add mobile, IP, device, and global abuse controls.
- Move permissions to reviewed, static, deny-by-default policy definitions.
- Remove wallet provisioning from the synchronous login path.
### Phase 5: Introduce the ledger
- Create versioned ledger migrations and invariants.
- Backfill opening balances with a documented source and timestamp.
- Build balance and statement projections.
- Introduce reservations for orders, withdrawals, purchases, BNPL, and redeem operations.
- Add transactional outbox publishing.
- Run old and new balance calculations in parallel and compare them continuously.
### Phase 6: Convert external flows
Migrate one flow at a time:
1. IRT deposit and payment callback.
2. IRT withdrawal.
3. Internal token transfer.
4. External token transfer.
5. Primary asset purchase.
6. Redeem and commission.
7. Market order reservation and settlement.
For each flow, require idempotency, durable state, compensation, reconciliation, and operational recovery procedures before cutover.
### Phase 7: Remove direct database consumers
- Route AdminPanel mutations through internal APIs.
- Move reporting to projections or a read replica.
- Remove old mutable balance code after parallel reconciliation reaches an agreed threshold.
- Separate ledger, settlement, or market into independent deployments only if scaling, ownership, or isolation requirements justify it.
## Missing considerations checklist
### Financial integrity
- [ ] Exact amount representation and asset-specific scale
- [ ] Double-entry and zero-sum enforcement
- [ ] Reservations, expirations, releases, and partial capture
- [ ] Reversal instead of mutation or deletion
- [ ] Unique business, provider, and blockchain idempotency keys
- [ ] Atomic compare-and-set state transitions
- [ ] Daily fiat, token-supply, PSP, and custody reconciliation
- [ ] Opening balance and migration reconciliation
- [ ] Negative balance and rounding policies
- [ ] Fee, tax, discount, and commission accounting
### Authentication and authorization
- [ ] Refresh-token family rotation and replay detection
- [ ] Logout, revoke-all, session expiry, and device management
- [ ] JWT key versioning, rotation, and emergency revocation
- [ ] Secure OTP generation, hashing, TTL, attempt limits, and abuse controls
- [ ] MFA bound to exact financial intent
- [ ] Static deny-by-default permissions
- [ ] Service-to-service identities and per-RPC authorization
- [ ] High-value transaction step-up policy
### Blockchain and custody
- [ ] HSM, KMS, or isolated signing service
- [ ] Master-key versioning and rotation
- [ ] Hot/cold wallet and treasury policy
- [ ] Sequence-number concurrency management
- [ ] Submission-unknown recovery
- [ ] Confirmation/finality definition
- [ ] Persistent stream cursor and replay procedure
- [ ] Gas and fee accounting
- [ ] Supply and custody reconciliation
- [ ] Key backup, restore drills, and compromise response
### Payments and messaging
- [ ] Webhook signature validation, timestamp, nonce, and replay protection
- [ ] Provider-specific idempotency and reference uniqueness
- [ ] Settlement, reversal, and refund state machines
- [ ] Transactional outbox and consumer inbox
- [ ] Durable queues and persistent messages
- [ ] Publisher confirms and mandatory routing
- [ ] Retry limits, exponential backoff, DLQ, and manual replay
- [ ] Event schema versioning and compatibility
### API and privacy
- [ ] Request body limits and HTTP server timeouts
- [ ] Per-route and per-identity rate limits
- [ ] Strict request validation and unknown-field handling
- [ ] Stable public error codes and status mapping
- [ ] Idempotency-key semantics and retention
- [ ] API versioning, deprecation, and consumer inventory
- [ ] Correct CORS and security headers
- [ ] Protected metrics, profiling, Swagger, and WebSocket endpoints
- [ ] PII encryption, redaction, retention, and deletion policy
- [ ] Immutable security and administrative audit trail
### Compliance and operations
- [ ] AML and suspicious-activity hooks
- [ ] User, asset, daily, and velocity limits
- [ ] Sanctions and risk screening integration points
- [ ] Maker-checker approval for administrative financial actions
- [ ] RPO, RTO, backup, restore, and disaster-recovery testing
- [ ] Incident response and key-compromise procedures
- [ ] Stuck-transaction and reconciliation-drift alerts
- [ ] Queue lag, chain lag, provider latency, and error budgets
- [ ] Capacity and load testing for high-volume events
### Delivery and testing
- [ ] Versioned database migrations and rollback/forward-fix policy
- [ ] Unit, integration, contract, concurrency, and property tests
- [ ] Deterministic Stellar, Redis, RabbitMQ, PostgreSQL, and PSP test environments
- [ ] Callback replay and service-restart tests
- [ ] Failure injection and reconciliation tests
- [ ] `go test`, race detector, vet, lint, and vulnerability scanning in CI
- [ ] Buf lint and breaking checks in CI
- [ ] Deployment health checks, readiness, graceful shutdown, and rollback gates
## Migration acceptance criteria
A flow should move to the new implementation only when:
- all monetary values use exact representation;
- repeat requests and callbacks produce one economic result;
- concurrent requests cannot overspend;
- every external action can be resumed after process restart;
- every state transition is auditable;
- ledger, PSP, and chain reconciliation is automated;
- old and new calculations agree within an explicitly approved tolerance;
- operational procedures exist for stuck, failed, unknown, and reversed operations;
- compatibility tests cover API, UI, AdminPanel, and protobuf consumers.
## Current verification status
This assessment is based on static inspection of the API, auth, wallet, protobuf, UI, AdminPanel, documentation, and CI configuration.
An attempt was made to run `go test ./...` for API, auth, and wallet. The configured internal Go module proxy timed out during dependency download, so the current compile status could not be independently verified. No source files were changed as part of that verification attempt.
+41
View File
@@ -28,6 +28,47 @@ Multi-service monorepo for the Darano financial/crypto platform.
- [overmind](https://github.com/DarthSim/overmind) or [foreman](https://github.com/ddollar/foreman) — Procfile runner
- PostgreSQL 16, Redis, RabbitMQ running locally (or via Docker)
## Clone the Workspace
The Darano workspace is an aggregate of independent Git repositories. These
commands reproduce the current directory layout and select the branches used by
this refactor. They expect the local branches to have been pushed first and
require SSH access to `git.darano.ir`.
```bash
mkdir darano
cd darano
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 dev 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 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/auth.git auth
git clone --branch main 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 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 feat/refactor-v1 git@git.darano.ir:Kahroba/wallet.git wallet
```
`private-chain/` is not included because the current local repository has no
`origin` remote configured.
Recreate the root documentation links after cloning:
```bash
ln -s dev-procfile/AGENTS.md AGENTS.md
ln -s dev-procfile/CLAUDE.md CLAUDE.md
ln -s dev-procfile/README-REFACTORING.md README-REFACTORING.md
ln -s dev-procfile/README.md README.md
ln -s dev-procfile/REFACTORING-AUDIT.md REFACTORING-AUDIT.md
ln -s dev-procfile/REFACTORING-PLAN.md REFACTORING-PLAN.md
ln -s dev-procfile/REFACTORING-TODO.md REFACTORING-TODO.md
ln -s dev-procfile/گزارش-زیرساخت-توکنسازی-دارانو.md گزارش-زیرساخت-توکنسازی-دارانو.md
```
## Infrastructure
Start the shared infrastructure (Postgres, Redis, RabbitMQ, MinIO):
+522
View File
@@ -0,0 +1,522 @@
# Darano Refactoring Audit
Audit date: 2026-08-14
Active repositories: `api`, `auth`, `wallet`, `AdminPanel`, `proto`.
Excluded and not audited: `ui`, `docs`, `DevOps`.
## Repository safety
| Repository | Branch | Initial state | HEAD at audit |
|---|---|---|---|
| `api` | `feat/refactor-v1` | Clean | `37b72f8` |
| `auth` | `feat/refactor-v1` | Clean | `1d4cba4` |
| `wallet` | `feat/refactor-v1` | Clean | `53b6901` |
| `AdminPanel` | `feat/refactor-v1` | Clean | `b4668d4` |
| `proto` | `feat/refactor-v1` | Existing untracked `buf-Linux-x86_64.bin` | `892ffc2` |
No nested `AGENTS.md` files were found in the active repositories. Root instructions therefore govern all active work.
## Findings that correct the planning documents
1. `api` uses `knadh/koanf/v2`; `auth` and `wallet` still use `kkyr/fig`. The refactoring plan is correct on this point, while the root `AGENTS.md` current-state summary is stale.
2. All three Go services expose global `config.Cfg` and read it throughout bootstrap, logging, transport, use-case, repository, and utility code.
3. Every current `ParseConfig` calls `(&sync.Once{}).Do(...)`. Because that creates a new `sync.Once` per invocation, configuration is not actually guarded by a process-wide once initializer.
4. API upstream connections are created through `grpc.NewClient`, health-checked on first acquisition, and closed by a two-minute context timer. The timer is not reset on subsequent use, so current behavior is a fixed connection lifetime rather than a true two-minute inactivity timeout.
5. `auth` application structs directly implement and embed generated public and internal gRPC server interfaces.
6. `wallet/core/{walletImp,marketImp,alertImp}` directly implements generated servers and mixes protobuf mapping, configuration, business rules, repositories, cryptography, and Stellar operations.
7. Repository interfaces live in top-level `repository` packages and use GORM-tagged structs from `domain/db`; domain and persistence representations are therefore conflated.
8. AdminPanel has BetterProto/grpclib dependencies and a generator configuration, but no application gRPC client integration was found. Its generator reads the remote `v2` proto branch rather than the local `proto` checkout.
9. AdminPanel writes directly through `MultiDBMixIn`, specialized admin classes, and signals. The unmanaged `coreLogic/models.py` replicas are used for both reads and writes.
10. `CoreRouter.no_migartion` is misspelled and is referenced by `allow_migrate`, confirming the planned router fix.
11. Existing internal wallet RPCs cover locking, commission operations, public-key lookup, and referral commission initialization. They do not currently expose general AdminPanel asset/wallet/market mutation operations.
12. Automated test coverage is extremely limited: the audit found only `wallet/repository/db/redis/lock_test.go` among conventional Go/Python test filenames in the active repositories.
## Generated-code boundaries
- `api`, `auth`, and `wallet` generate Go protobuf code into `domain/stub/go` from the local root `proto` directory.
- Their Buf generation configurations use `clean: true`; generation replaces output directories.
- Generated Go stubs are marked `DO NOT EDIT` and must remain mechanically generated.
- AdminPanel generates BetterProto Python code into `src/stub`, currently from a remote repository branch.
- Root `proto/buf.gen.yaml` generates Go, documentation, gateway, and TypeScript artifacts under `proto/stub`; the root repository has no Makefile.
- The existing untracked `proto/buf-Linux-x86_64.bin` is user-owned baseline state and must not be removed or committed implicitly.
## Current architecture map
### `api`
- Bootstrap: `cmd/serve.go`
- Configuration: `config/config.go`
- HTTP adapters: `handler/`
- Middleware: `middlewares/`
- Upstream gRPC aggregation: `service/`
- Generated contracts: `domain/stub/go/`
- Notable compatibility constraints: middleware order, response envelopes, HTTP-to-gRPC metadata, reflection-based peer field lookup, connection lifetime behavior, Swagger environment mapping, profiling, metrics, WebSocket.
### `auth`
- Bootstrap and gRPC registration: `cmd/serve.go`
- Configuration: fig-based `config/config.go`
- Business and gRPC implementation: `usecase/`
- Repository ports and aggregate: `repository/`
- PostgreSQL/Redis/service implementations: `repository/db/` and `repository/service/`
- Persistence models: GORM-tagged `domain/db/`
- Generated contracts: `domain/stub/go/`
### `wallet`
- Multi-mode bootstrap: `cmd/` and `cmd/cmdServe/`
- Configuration: fig-based `config/config.go`
- Business and gRPC implementation: `core/walletImp`, `core/marketImp`, `core/alertImp`
- Cron orchestration: `core/cronJobs`
- Repository ports and aggregate: `repository/`
- PostgreSQL, Redis, queue, mailer, and service implementations: `repository/`
- Stellar implementation: `port/stellar`
- Persistence models: GORM-tagged `domain/db/`
- Generated contracts: `domain/stub/go/`
### `AdminPanel`
- Shared direct-write behavior: `src/utils/base_admin.py`
- Business rules and specialized writes: `src/coreLogic/admin/`
- Additional write side effects: `src/coreLogic/signals.py`
- Database router: `src/adminpanel/db/routers.py`
- Legacy unmanaged models: `src/coreLogic/models.py`
- Generated Python target: `src/stub/`
### `proto`
- Source packages: `base/v1`, `errors/v1`, `auth/v1`, `wallet/v1`, `market/v1`, `alert/v1`
- Buf lint policy: BASIC plus package/import rules; breaking policy: FILE
- Contract changes must remain backward-compatible and be justified by a proven service-layer gap.
## Migration implications
1. Configuration loader migration and removal of globals must be separate tasks. First preserve parsing behavior, then inject configuration into progressively deeper dependencies.
2. Current fixed connection lifetime and config reparse behavior are compatibility baselines, even if they appear unintended. Tests must capture them before an intentional correction.
3. Package moves must proceed through vertical slices because existing test coverage cannot protect a repository-wide rename.
4. AdminPanel mutation inventory and RPC gap analysis must happen before protobuf edits.
5. AdminPanel should eventually generate against the local proto checkout during coordinated changes, but switching its source is a separate, verified task.
## Toolchain and dependency baseline
| Tool | Baseline |
|---|---|
| Go | `go1.26.5-X:nodwarf5 linux/amd64`; active modules declare Go `1.24`; `GOTOOLCHAIN=auto` |
| Python | `3.14.6` |
| uv | `0.12.2` |
| Django | `5.2.14` |
| Buf | `/usr/bin/buf`, `1.72.0` |
| protoc | `35.1` |
| protoc-gen-go | `1.36.11` |
| protoc-gen-go-grpc | `1.6.2` |
| swag | `1.16.4` |
| air | `1.66.0` |
| BetterProto | `1.2.5` |
| grpclib | `0.4.9` |
The committed `go.mod`, `go.sum`, `AdminPanel/pyproject.toml`, and `AdminPanel/uv.lock` are the dependency baseline. No dependency was upgraded. Notable direct versions include API koanf `2.3.4`, auth/wallet fig `0.5.0`, API gRPC declaration `1.62.1`, auth/wallet gRPC declaration `1.67.1`, and the shared replacement of gRPC with `1.64.0` in all three modules.
The local untracked Buf file is mode `0644`, size `54,050,978` bytes, SHA-256 `8720830e26a733da55bb89bcd3cb44849c0965fc0c44fb5d691cccdc64dca5af`; it is not executable. `protoc-gen-doc` and `protoc-gen-es` are absent, while `protoc-gen-grpc-gateway` is installed. Root proto generation therefore has known missing-tool preconditions.
A read-only `go list -m all` succeeded from the local cache for auth and wallet. API enumeration attempted to contact the configured private Go proxy and was sandbox-blocked; committed module files remain sufficient and authoritative for the no-upgrade baseline.
## Baseline check results
### `proto`
- `buf build`: passed.
- `buf lint`: passed after redirecting Buf's cache to a writable temporary directory; the default cache location is read-only in the workspace sandbox.
- `buf format --diff --exit-code`: failed with existing formatting differences in alert, base, errors, market, and wallet proto files. No formatting changes were applied.
- Exact root `buf generate` in a temporary clone: failed because `protoc-gen-doc` and `protoc-gen-es` are not installed. Other plugins were canceled after those failures.
- The active proto working tree remained unchanged, and the pre-existing untracked Buf binary retained its original SHA-256.
### `auth`
- `make build-proto`: passed in a temporary clone and reproduced committed stubs with no diff.
- `make test`: passed; every package reports no test files.
- `make build`: passed and produced the service binary.
- The active auth working tree remained unchanged.
### `wallet`
- `make build-proto`: passed and reproduced committed stubs, including the intentional `omitempty` removal, with no diff.
- `make test`: passed; the Redis lock package test passed and all other packages report no test files.
- `make build`: passed, including generation, formatting/tidy, and binary creation, with no tracked diff afterward.
- The active wallet working tree remained unchanged.
- Cross-process `flock` is implemented by the `air-build` target. `.NOTPARALLEL` only serializes targets within one Make invocation, so refactor checks will continue to avoid concurrent standalone generation/build commands.
### `api`
- `make build-proto`: passed and reproduced committed stubs, including intentional `omitempty` removal, with no diff.
- `make test`: passed; every package reports no test files.
- `make build`: passed, including go/swag formatting, tidy, protobuf generation, Swagger generation, and binary creation.
- Generated protobuf and Swagger outputs are reproducible with the installed tools; the temporary clone remained clean after the build.
- The active API working tree remained unchanged.
### `AdminPanel`
- `manage.py check`: passed with no issues.
- `manage.py check --deploy`: exited successfully but reports six existing security warnings for HSTS, SSL redirect, weak/development secret key, secure session/CSRF cookies, and DEBUG.
- `manage.py test --noinput`: discovered zero tests and failed its system check because Django Debug Toolbar is enabled while Django forces DEBUG false for tests.
- `makemigrations --check --dry-run`: passed with no model migration drift.
- Python bytecode compilation: passed.
- No database migrations were run, no application database was modified, and the active working tree remained clean.
## First migration slice
The first code task is `C001`, limited to auth configuration ownership and parsing:
1. Add `auth/infrastructure/config` as the owner of config types and a pure `Load(path) (*Config, error)` function based on koanf/TOML.
2. Preserve all existing TOML keys, types, durations, peer field capitalization, and actual reparse behavior.
3. Keep `auth/config` temporarily as a compatibility facade so `C001` does not also perform global dependency injection.
4. Add synthetic loader tests that do not read or expose repository secrets.
5. Remove fig and add the same pinned koanf packages already used by API.
6. Run generation, tests, and build; require a clean generated diff and no behavior changes outside configuration parsing.
Global config removal remains the separate follow-up `C002`.
## Implementation progress
### `C001` — auth configuration ownership and koanf loader
- Added `authorization/infrastructure/config` with config types and a pure, error-returning TOML loader.
- Replaced fig tags/dependency with pinned koanf packages matching API.
- Retained `authorization/config` as an explicitly temporary compatibility facade; its global API and effective reload-on-each-call behavior are preserved for `C002`.
- Added synthetic tests for flags, durations, GORM level, uppercase peer keys, missing files, independent loads, and legacy facade reloads.
- Proto generation remained reproducible; full tests, targeted race tests, and binary build passed.
- `go vet ./...` still reports the same two pre-existing findings as the untouched baseline: unreachable code in `logger/main.go` and a discarded timeout cancel in `usecase/identity.go`.
- Auth commit: `29b7e07 refactor(auth): move config loading to infrastructure`.
### `C002` — auth configuration injection
- Auth configuration is now loaded once in `cmd/serve.go` and passed explicitly into database, Redis, upstream-service, repository-system, use-case, gRPC-server, profiling, logger, and JWT utility boundaries.
- JWT helpers receive the narrow `JWTModel` value rather than consulting process state.
- PostgreSQL now uses its constructor argument for GORM log level instead of reading a global.
- The legacy `authorization/config` facade and `Cfg` global were removed.
- Source scans confirm no production `config.Cfg`, `Cfg` global, or legacy config import remains.
- Full tests, full race tests, proto generation, module tidy, and binary build passed. Vet remains limited to the two confirmed baseline findings.
- Auth commit: `1bd5559 refactor(auth): inject service configuration`.
### `C003` — wallet configuration ownership and koanf loader
- Added `wallet/infrastructure/config` with pure TOML loading and retained `wallet/config` as a temporary compatibility facade for `C004`.
- Reproduced measured fig defaults: page size 50, gRPC timeout 1s, Redis port/DB/mutex defaults, cron timings/retries, log level, nil SMTP without a section, and SMTP port/auth defaults with a section.
- Added tests for defaults, nested overrides, durations, uppercase peer keys, missing files, independent load state, legacy facade reloads, and all five committed service-mode config files.
- Removed fig and pinned the same koanf packages used by API/auth.
- Proto output remained reproducible; full tests, targeted race tests, module tidy, and full build passed.
- 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`.
### `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 A002A008 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
- Compatibility entrypoints remain `WalletService.CalcBuyAsset` and `WalletService.BuyAsset`; API routes and existing request fields do not move.
- `MarketplaceSrv` owns order selection, pricing, taker creation, and settlement. Wallet delegates instead of retaining a second ICO transfer implementation.
- A publisher creates the normal maker/sell order with an additive ICO designation. The designation is accepted only when IAM contains the `token-publisher` role key; normal orders retain their current authorization behavior.
- Auth supplies additive IAM role keys because database role IDs are deployment-local and must not be hard-coded in wallet.
- An ICO quote selects an open, designated maker/sell order for the requested asset against IRT, validates remaining volume, and returns its order ID additively in `CalcBuyAssetRes`.
- `GenerateBuyContract` pins that maker-order ID in `ICOAgreements`, preventing confirmation from silently switching price or publisher.
- `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.
- 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. Auths 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.
+301
View File
@@ -0,0 +1,301 @@
# Darano Monorepo — DDD / Clean Architecture Refactoring Plan
## Executive Summary
The five codebases (`api/`, `auth/`, `wallet/`, `AdminPanel/`, and `proto/`) share the same general idea of layering but diverge in naming, directory structure, config libraries, where business logic lives, and — critically for AdminPanel — **how they access data**. AdminPanel bypasses all Go backend services and writes directly to the core database, making it a parallel implementation of business logic. This plan defines a unified target architecture and a phased migration that preserves functionality at every step.
---
## 1. Current State Analysis
### 1.1 Naming & Structure Inconsistencies
| Concern | `api/` | `auth/` | `wallet/` |
|---|---|---|---|
| Business logic layer | `handler/` (HTTP-only) | `usecase/` | `core/walletImp/` |
| Business logic layer (2nd) | `service/` (gRPC client) | (same as above) | `core/marketImp/`, `core/alertImp/` |
| Data access | No repo (gateway only) | `repository/` | `repository/` |
| Domain models | `domain/stub/` only | `domain/db/` + `domain/dto/` | `domain/db/` |
| Config library | `knadh/koanf` | `kkyr/fig` | `kkyr/fig` |
| Config global | `config.Cfg` | `config.Cfg` | `config.Cfg` |
| gRPC server impl | N/A (HTTP-only) | `usecase/*` implements gRPC server | `core/*Imp/*` implements gRPC server |
**Key observation**: `auth/` has the cleanest pattern (`usecase/` for business logic), `wallet/` is the most messy (`core/` mixes gRPC server with business logic), and `api/` is fine as an HTTP gateway.
### 1.2 AdminPanel Architecture — Direct DB Access, No Abstraction
AdminPanel has a fundamentally different problem: it **bypasses all Go backend services** and connects directly to the core database.
```
AdminPanel ──direct Postgres──→ core_db (same DB as Go services)
──→ default_db (Django's own tables)
──→ lite_db (SQLite, fallback)
```
**Key problems**:
1. **`managed = False` GORM models copied manually**: Every model in `src/coreLogic/models.py` has `managed = False` and `db_table = "..."` — they are **manual replicas** of the Go services' GORM models. Generated via `inspectdb`, never kept in sync. `make proto` generates betterproto stubs, but Django models are **not auto-generated** from those.
2. **No service layer**: The entire AdminPanel is a thin layer of Django admin widgets on top of raw SQL tables. Business logic is scattered across:
- `src/coreLogic/admin/asset.py` — inline validation (`check_token_policy`, `auto_gen`) duplicating Go-side rules
- `src/coreLogic/acl.py` — permission rules
- `src/usermapper/user_perm.py` — asset access control
- Inline admin methods (`save_model`) that bypass Go services' validation entirely
3. **No gRPC integration**: The AdminPanel reads/writes directly to `core_db`. No gRPC call to Go services. Means:
- Admin edits to `Assets` bypass trustline updates
- Admin edits to `Transactions` don't trigger blockchain operations
- Admin edits to `Wallets` don't update Stellar balances
- Race conditions between admin edits and Go service operations
4. **Hardcoded business rules in Django**: `check_token_policy` duplicates validation that should live in the wallet service. `auto_gen` generates metadata that should be produced by the wallet service.
5. **Multi-database with fragile router**: `src/adminpanel/db/routers.py` routes `coreLogic` models to `core_db`. If a new model is added to Go services but forgotten in Django admin, it silently fails.
6. **Inline business logic in Django admin**: `MultiDBModelAdmin.save_model` has asset-level access control. `delete_model` does soft deletes. Mixed with admin layer, not separated.
### 1.3 Config Library Mismatch
- `api/` uses `knadh/koanf/v2` with TOML parser. Tags are `koanf:"field-name"`.
- `auth/` and `wallet/` use `kkyr/fig`. Tags are `fig:"field-name"`.
- All three use a **global singleton** `config.Cfg`.
- `api/` hardcodes defaults in `ParseConfig`; `auth/` and `wallet/` rely on struct defaults.
- AdminPanel uses `django-environ` (`.env` files). Different language/framework entirely.
### 1.4 Where Business Logic Lives
- **auth/ `usecase/`** — Decent separation, but gRPC interfaces embedded directly in the struct. Validation, business rules, and gRPC response building mixed in the same methods.
- **wallet/ `core/walletImp/`** — Problematic: 19 files implementing `WalletServiceServer` with business logic, validation, DB calls, and Stellar blockchain calls all in one method. Example: `UserInitWallet` does validation, DB transactions, key generation, trustline creation, and status response — all in one method.
- **api/ `handler/`** — Acceptable: handlers call `DaranoService` (gRPC client). No business logic here. But `service/` is a gRPC client aggregator with reflection-based URL lookup, not a traditional service layer.
- **AdminPanel `admin/`** — Wrong layer: business validation, metadata generation, and policy checks live in Django admin classes, not in a service layer.
### 1.5 Domain Model vs Persistence Model Confusion
All Go services use GORM models (`domain/db/`) directly as domain objects. No separation between **domain entities** (rich business objects with behavior) and **persistence models** (plain structs with GORM tags).
AdminPanel uses Django models with `managed = False` — the same conflation, but in Python.
---
## 2. Target Architecture
### 2.1 Go Services — Unified Directory Structure
Each Go service should follow:
```
service/
├── cmd/ # CLI entry points (Cobra)
├── domain/ # Innermost layer — pure business logic
│ ├── entity/ # Domain entities (rich, no persistence tags)
│ ├── valueobject/ # Immutable value objects (Money, AssetID, etc.)
│ ├── service/ # Domain services (orchestrate entities)
│ ├── repository/ # Repository INTERFACES only (ports)
│ ├── error/ # Domain-specific errors
│ ├── event/ # Domain events
│ ├── dto/ # Data transfer objects (gRPC/HTTP)
│ └── stub/ # Generated protobuf code (never edit)
├── application/ # Application layer — use cases
│ ├── usecase/ # Business logic / use cases
│ └── service/ # Application services
├── infrastructure/ # Infrastructure layer
│ ├── repository/ # Repository implementations (DB, Redis, Queue)
│ │ ├── db/ # PostgreSQL, etc.
│ │ ├── redis/ # Redis
│ │ └── queue/ # RabbitMQ
│ ├── config/ # Configuration loading
│ ├── grpc/ # gRPC server setup & registration
│ ├── logger/ # Logger initialization
│ └── crypto/ # Cryptography utilities
├── interface/ # Interface/Adapter layer
│ ├── http/ # HTTP handlers (api gateway only)
│ ├── grpc/ # gRPC server implementations
│ └── ws/ # WebSocket handlers
├── util/ # Cross-cutting utilities
├── go.mod
└── main.go
```
**Dependency flow** (points inward):
```
interface/ → application/ → domain/ ← infrastructure/
```
### 2.2 AdminPanel — Thin Admin Wrapper Around Go Services
AdminPanel needs a Django-native approach (no forced DDD naming), but the architectural principles are the same:
```
AdminPanel/src/
├── adminpanel/ # Django project config
├── coreLogic/
│ ├── domain/ # NEW: extracted business logic
│ │ ├── services/ # Validation, metadata generation (moved from admin/)
│ │ └── repositories/# Interfaces to backend
│ ├── application/ # NEW: use cases that delegate to gRPC
│ │ ├── asset_uc.py
│ │ ├── wallet_uc.py
│ │ └── market_uc.py
│ ├── infrastructure/ # NEW: gRPC client to Go services
│ │ └── grpc_client.py
│ ├── admin/ # Keep — now thin UI adapters only
│ ├── models.py # Keep as legacy (read-only ORM, managed=False)
│ └── enums.py # Keep
├── usermapper/ # Admin user management (keep as-is)
├── alerts/ # Notification system (keep as-is)
├── accounts/ # SMS accounts (keep as-is)
└── utils/ # Cross-cutting utilities
```
**Key principle**: AdminPanel should be a **thin admin wrapper** around the Go services, not a parallel implementation. Go services own all business logic. AdminPanel provides a human-friendly interface to view and (with validation) modify state.
### 2.3 AdminPanel Data Access Pattern
```
Read path: AdminPanel ──SQL──→ core_db (fast, direct, for list/detail views)
Write path: AdminPanel ──gRPC──→ Go services (validate + execute business logic)
```
### 2.4 Config Standardization
All Go services → `knadh/koanf/v2` with TOML. No global singletons — config passed via constructor injection.
---
## 3. Migration Plan — Phased Approach
### Phase 0: Preparation (1 day)
No code changes. Document test coverage, verify all services build, create tracking doc.
### Phase 1: Standardize Go Config (2-3 days)
Replace `fig``koanf` in `auth/` and `wallet/`. Move config to `infrastructure/config/config.go`. Remove global `config.Cfg`.
**Risk**: Low. Config struct fields stay the same; only the loader changes.
### Phase 2: Reorganize `auth/` (3-4 days)
Rename layers, move interfaces to `domain/`, move GORM models to `infrastructure/`. `auth/` already has the cleanest pattern — this validates the approach.
**Risk**: Low. Structure change, minimal logic changes.
### Phase 3: Reorganize `wallet/` (1-2 weeks)
Rename `core/``application/`. Split `walletImp/`, `marketImp/`, `alertImp/` into `application/usecase/`. Move GORM models and interfaces. Split gRPC server registration from use cases. Move `port/stellar/``infrastructure/`.
**Risk**: Medium. Incremental: rename first, then split gRPC, then add entities.
### Phase 4: Restructure `api/` (3-4 days)
Rename `handler/``interface/http/`, `service/``infrastructure/grpcclient/`, move `middlewares/``interface/http/middleware/`.
**Risk**: Medium. Gateway pattern is different from auth/wallet.
### Phase 5: AdminPanel Service Layer (2-3 weeks)
1. Create `infrastructure/grpc_client.py` — reusable gRPC client to Go services
2. Extract business logic from admin classes to `coreLogic/domain/services/`
3. Create use case layer `coreLogic/application/`
4. Refactor admin classes to thin adapters (delegate to use cases)
5. Fix router typo (`no_migartion``no_migration`)
6. Add gRPC write hooks for `save_model`
**Risk**: Medium. Test every admin page after migration.
### Phase 6: Shared Domain Types (3-5 days)
Extract `WalletID`, `UserID`, `AssetID`, `Balance` value objects into monorepo root `shared/domain/`. Import via each service's `go.mod`.
**Risk**: Medium. Affects all services on change.
### Phase 7: Domain Events (2-3 days, optional)
Add `domain/event/` to Go services for cross-domain communication.
---
## 4. Migration Order
```
Phase 0: Preparation
Phase 1: Go config standardization
Phase 2: Reorganize auth/ ──┐
├──→ Phase 5: AdminPanel (parallel with 2-4)
Phase 3: Reorganize wallet/ ─┘
Phase 4: Restructure api/
Phase 6: Shared domain types
Phase 7: Domain events (optional)
```
---
## 5. Before/After: AdminPanel Asset Management
**Before** — business logic in Django admin:
```python
# src/coreLogic/admin/asset.py
@admin.register(Assets, site=admin_site)
class AssetAdmin(MultiDBModelAdmin):
def save_model(self, request, obj, form, change):
if user_perm.can_access_asset(request.user, obj):
return super().save_model(request, obj, form, change)
# Direct DB write — bypasses wallet service!
def check_token_policy(self, request, obj: Assets) -> bool:
# Validation duplicated from wallet service
if obj.can_buy:
p = AssetPrices.objects.filter(asset=obj).last()
if not p or p.ico_price <= 0:
errors.append("ico price must be > 0")
```
**After** — thin admin delegating to Go service:
```python
# src/coreLogic/application/asset_uc.py
class AssetUseCase:
def __init__(self, grpc_client: GRPCClient):
self.grpc_client = grpc_client
def update_asset(self, admin_user, asset_id, changes: dict) -> StatusRes:
"""Delegates all mutations to wallet service."""
return self.grpc_client.wallet_service.InternalWalletUpdateAsset(
AssetUpdateReq(id=asset_id, changes=changes)
)
# src/coreLogic/admin/asset.py
@admin.register(Assets, site=admin_site)
class AssetAdmin(MultiDBModelAdmin):
list_display = [...]
# ... UI config only
def save_model(self, request, obj, form, change):
uc = AssetUseCase(self.grpc_client)
uc.update_asset(request.user, obj.id, form.cleaned_data)
```
---
## 6. Risk Mitigation
| Risk | Mitigation |
|---|---|
| Breaking CI/CD | Keep `make build` and `make run` working at every phase |
| Lost functionality during rename | Use `git mv` + `sed` for mass renames; commit each file move separately |
| gRPC contract breaks | Proto definitions are in `proto/`. We only change Go implementation |
| Config migration issues | Keep old config format identical; only change the loader |
| AdminPanel write conflicts | gRPC write path ensures Go services own all mutations |
| Django model drift | Document which models are read-only ORM vs which need gRPC sync |
| Multiple air instances conflict | The `flock` mechanism in wallet Makefile handles this |
## 7. Non-Goals
- Changing protobuf definitions — `.proto` files stay as-is
- Adding new frameworks — no ORM replacement
- Rewriting the UI
- Complete test suite rewrite
+350
View File
@@ -0,0 +1,350 @@
# Darano Refactoring Task Tracker
This is the authoritative execution tracker for the refactor. Work is performed sequentially, with no more than one task marked `STARTED` at a time.
## Status rules
| Status | Meaning |
|---|---|
| `TODO` | Ready or waiting on an earlier task. |
| `STARTED` | The single task currently being executed. |
| `DONE` | Implemented and verified against its acceptance checks. |
| `FAILED` | Attempted but not completed; failure evidence and a follow-up task must be recorded. |
| `CHANGED` | The task or scope changed after it was recorded; the reason must be retained. |
## Scope
| ID | Status | Task | Acceptance check / note |
|---|---|---|---|
| S001 | `DONE` | Read root `AGENTS.md`, `REFACTORING-PLAN.md`, and RTK instructions. | Governing instructions incorporated into the tracker. |
| S002 | `CHANGED` | Refactor every repository originally listed in the plan. | Scope changed: `ui`, `docs`, and `DevOps` are excluded; new `GL` is included by user request. |
| S003 | `CHANGED` | Define active repositories. | Active scope changed to `api`, `auth`, `wallet`, `AdminPanel`, `proto`, and `GL`. |
| S004 | `DONE` | Create `feat/refactor-v1` in every active repository. | Branch exists and is checked out in all six active repositories. |
| S005 | `DONE` | Restore excluded repositories after the scope change. | `ui` is on `stage`, `docs` is on `dev`, and `DevOps` is on `m2`; their temporary refactor branches were removed without changing their files. |
## Phase 0 — Baseline and safety
| ID | Status | Task | Acceptance check / note |
|---|---|---|---|
| B001 | `DONE` | Audit active repositories and reconcile plan claims with actual code. | Findings recorded in `REFACTORING-AUDIT.md`, including corrected config and connection-lifecycle claims. |
| B002 | `DONE` | Record toolchain and dependency baselines. | Versions and committed dependency sources recorded in `REFACTORING-AUDIT.md`; no upgrades performed. |
| B003 | `DONE` | Run `proto` baseline checks. | Build/lint pass; existing format differences and missing generation plugins recorded; active tree and binary preserved. |
| B004 | `DONE` | Run `auth` baseline checks. | Generation, tests, and build pass in a clean temporary clone; generated stubs are reproducible. |
| B005 | `DONE` | Run `wallet` baseline checks. | Generation is reproducible; Redis lock test and build pass serially with no diff. |
| B006 | `DONE` | Run `api` baseline checks. | Proto/Swagger outputs are reproducible; tests and full build pass with no diff. |
| B007 | `DONE` | Run `AdminPanel` baseline checks. | System/compile/migration checks pass; zero-test Debug Toolbar failure and deploy warnings recorded. |
| B008 | `DONE` | Produce the baseline report and lock the first migration slice. | Baseline and exact `C001` compatibility-facade migration are documented in `REFACTORING-AUDIT.md`. |
## Phase 1 — Configuration standardization
| ID | Status | Task | Acceptance check / note |
|---|---|---|---|
| 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`. |
| C003 | `DONE` | Refactor `wallet` config loading into `infrastructure/config`. | Fig defaults and all five configs verified; tests/race/build pass; committed as `7958530`. |
| 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 | `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 | `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`)
| ID | Status | Task | Acceptance check / note |
|---|---|---|---|
| L001 | `DONE` | Define GL invariants, transaction mapping, failure semantics, and service boundary. | `GL/DESIGN.md` defines the append-only double-entry model, mappings, outbox delivery, controlled failover modes, and gRPC ownership; committed as `1863de1`. |
| L002 | `DONE` | Add backward-compatible internal GL protobuf contracts. | Added isolated `ledger.v1` append, event, query, balance, health, and replay contracts; Buf format/lint/build pass; committed as `b4bb506`. |
| L003 | `DONE` | Scaffold `GL` as an independent Go gRPC service. | Added generated consumers, explicit composition, pure koanf config, health RPC, bounded graceful shutdown, and tests; generation/test/race/vet/build pass; committed as `b1e0b01`. |
| L004 | `DONE` | Implement GL PostgreSQL persistence and migrations. | Exact fixed-point domain values, transactional idempotent append, per-asset seal checks, immutable tables/triggers, migrations, and repository tests pass; committed as `0b3eaa0`. |
| L005 | `DONE` | Implement GL application use cases and gRPC adapters. | Append/event/query/balance/replay RPCs, canonical hashes, exact reversals, status mapping, persistence queries, and tests pass; committed as `76905ab`. |
| 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`. |
| 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 | `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 | `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
| ID | Status | Task | Acceptance check / note |
|---|---|---|---|
| I001 | `DONE` | Map the current `CalcBuyAsset`, `BuyAsset`, role/permission, market-order, and settlement paths. | Compatibility boundary and exact market-owned implementation are recorded in `REFACTORING-AUDIT.md`. |
| I002 | `DONE` | Add the `token-publisher` auth role and expose stable role keys in IAM. | Additive proto committed as `2d7d3ff`; idempotent custom-role bootstrap and stable role-key tests committed as `7c3b3b6`; auth tests/race/build pass. |
| I003 | `DONE` | Add a backward-compatible publisher ICO order contract and persistence linkage. | Additive proto committed as `286b8e5`; role-gated ICO sell-order designation and agreement maker linkage committed as `25d0f03`. |
| I004 | `DONE` | Refactor `CalcBuyAsset` to quote against the publisher's live sell order. | Market selects the best live publisher order, verifies the publisher role and remaining volume, calculates taker pricing, and wallet delegates; committed as `5a0f3d7`. |
| I005 | `DONE` | Refactor `BuyAsset` to create the user taker side and invoke the market settlement path. | Claim-once agreement, taker creation, maker-wide serialization, fresh-state checks, shared `settleOrder`, and synchronous hashes committed as `ef2e4ae`. |
| I006 | `DONE` | Verify publisher-backed ICO authorization, limits, quoting, settlement, ledger, and regressions. | Publisher/order/volume and claim tests pass; proto lint/build, reproducible generation, full auth/wallet/api tests, race tests, and builds pass; verification is `3555a5f`, with deterministic best-price selection corrected in `0d7c820`. |
## Priority workstream — Transaction event pipeline
| ID | Status | Task | Acceptance check / note |
|---|---|---|---|
| E001 | `DONE` | Map every transaction write, existing RabbitMQ code, GL outbox, transaction consumer, and alert boundary. | All transaction inserts/updates converge in the PostgreSQL transaction repository; direct AMQP publishing is legacy and inactive; the durable DB outbox is the required publication boundary. |
| E002 | `DONE` | Define transaction event identity, per-type topics, durable outbox, inbox, and deadbox persistence. | All 17 enum values have unique topics; transaction ID is the event identity; atomic outbox, inbox claim states, and deadbox models/repositories are tested and committed as `5dfb223`. |
| E003 | `DONE` | Replace the legacy AMQP channel wrapper with Watermill publisher/subscriber adapters. | Application code depends only on transport-neutral ports; AMQP connection ownership is centralized and can be replaced by another Watermill backend; full Wallet tests pass in `25fdb37`. |
| E004 | `DONE` | Add per-transaction-type handlers with idempotent inbox processing. | Every declared transaction type has a channel; duplicate delivery cannot repeat processing; pending executable transactions use the existing transaction processor; tests/race tests pass in `951cd02`. |
| E005 | `DONE` | Add retry, success notification, and deadbox routing. | Handler errors retry with bounded backoff; successful handling notifies alert; exhausted messages enter a persistent deadbox with transaction/event/error metadata; tests/race tests pass in `c9a9101`. |
| E006 | `DONE` | Integrate dispatcher/router lifecycle and verify the full event pipeline. | Wallet-mode-only startup/shutdown is bounded; outbox recovery, duplicate delivery, all 17 per-type routes, retry, deadbox, Alert success, generation, tests, race tests, vet, and build pass in `b5784b7`. |
## Priority workstream — Go 1.26 toolchain
| ID | Status | Task | Acceptance check / note |
|---|---|---|---|
| T001 | `DONE` | Inventory active Go modules, builders, and version pins while excluding docs, DevOps, and UI. | Four Go modules found; API/Auth/Wallet builders already use the official Go 1.26 Bookworm image; GL has no Dockerfile. |
| T002 | `DONE` | Upgrade API module metadata to Go 1.26 and verify its existing Docker builder. | Generation, tests, vet, and native build pass in `fb6ad38`; Docker proxy default changed in `ed8da2f`; Dockerfile check passes. |
| T003 | `DONE` | Upgrade Auth module metadata to Go 1.26 and verify its existing Docker builder. | Generation, tests, vet, and native build pass in `b2d6686`; Docker proxy default changed in `736a716`; Dockerfile check passes. |
| T004 | `DONE` | Upgrade Wallet module metadata to Go 1.26 and verify its existing Docker builder. | Generation, tests, full race tests, vet, and native build pass in `f5243a8`; Docker proxy default changed in `fc96120`; Dockerfile check passes. |
| T005 | `DONE` | Upgrade GL module metadata to Go 1.26 and add its missing Go 1.26 Dockerfile. | Scoped upgrade and new multi-stage image committed in `ce5f8b4`; Dockerfile check passes. Current-tree build validation changed because separate uncommitted GL explorer work is missing generated components. |
| T006 | `DONE` | Perform cross-repository version and clean-tree audit. | All four active Go modules and builders declare Go 1.26; all six active repositories use `feat/refactor-v1`; unrelated GL work and the known proto binary remain preserved. |
| T007 | `DONE` | Standardize in-scope Go Docker builders on the Darano Go proxy. | All four builders default to `https://go.reg.darano.ir`; Dockerfile checks pass. A cold API image build was stopped after repeated delayed proxy 404s for historical transitive metadata; no public fallback was added. |
| T008 | `DONE` | Execute full Docker image builds for every in-scope Go service. | GL passes and produced image `sha256:717c75dfa91f843acdb8d56b4dd111224e5ee45d060dcd4731e5d472ff2c8f69`; API, Auth, and Wallet are blocked in `go mod download` by repeated 300-second `504 Gateway Timeout` responses from `go.reg.darano.ir` for `google.golang.org/api` metadata. |
| T009 | `DONE` | Add Gitea CI/CD configuration to GL. | Seven action/workflow YAML files parse successfully; the exact buildx action produced both GL OCI tags using the mandated proxy; committed as `675def5`. |
| T010 | `DONE` | Commit outstanding workspace work and centralize root Markdown files in `dev-procfile` with root symlinks. | Pending work committed in DevOps (`665fd6b`), docs (`2c49a92`), Kuknos Node scripts (`c114c13`), and proto (`c778fda`); all eight root Markdown paths resolve through relative symlinks to tracked files in `dev-procfile`. |
| T011 | `DONE` | Document commands for cloning the complete Darano workspace on another machine. | `README.md` now has copy-paste commands for all 12 repositories with configured origins, pins the current branches, recreates all eight root Markdown symlinks, and identifies `private-chain` as lacking a clone URL. |
| T012 | `DONE` | Push every committed project branch required for cross-machine continuation. | All 12 top-level repositories with configured origins are synchronized; AdminPanel, Auth, and Proto refactor branches now have upstreams; `dev-procfile` uses SSH for non-interactive access; `private-chain` remains local because it has no remote. |
## Phase 2 — `auth` architecture
| ID | Status | Task | Acceptance check / note |
|---|---|---|---|
| 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 | `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 | `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 | `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 | `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 | `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 | `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 | `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
| ID | Status | Task | Acceptance check / note |
|---|---|---|---|
| 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 | `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 | `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 | `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 | `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 | `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 | `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 | `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 | `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 | `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 | `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 | `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
| ID | Status | Task | Acceptance check / note |
|---|---|---|---|
| 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 | `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 | `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 | `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 | `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 | `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 | `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 | `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
| 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. |
| P002 | `TODO` | Compare required AdminPanel mutations with existing internal RPCs. | Every missing contract is documented before any proto change. |
| P003 | `TODO` | Add reusable authenticated, deadline-aware gRPC client infrastructure. | Unit tests cover success, timeout, unavailable service, and status translation. |
| 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. |
| P005 | `TODO` | Move token-policy validation and metadata generation to Go-owned operations. | Django no longer owns duplicate wallet business rules. |
| P006 | `TODO` | Add wallet and transaction use cases and migrate writes. | Direct writes stop and failure/partial-write behavior is tested. |
| P007 | `TODO` | Add market and remaining mutable aggregate use cases. | All classified mutations use their owning service. |
| P008 | `TODO` | Make legacy unmanaged ORM models explicitly read-only. | List/detail reads remain fast; migrated writes cannot bypass services. |
| P009 | `TODO` | Fix `no_migartion` to `no_migration` with router tests. | Correct router setting is covered without unintended migrations. |
| P010 | `TODO` | Verify every affected admin page and permission tier. | Create/update/delete/inline/bulk/failure paths pass. |
## Phase 6 — Protobuf contracts
| 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. |
| R002 | `TODO` | Add backward-compatible internal RPCs only for proven gaps. | Buf lint/breaking checks pass; existing field numbers and contracts are preserved. |
| R003 | `TODO` | Regenerate only active Go and Python consumers. | Generated files are reproducible and Go JSON tags retain required field presence. |
## Phase 7 — Shared types and final verification
| 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. |
| F002 | `TODO` | Introduce approved shared types incrementally, if justified. | Versioned dependency and explicit boundary conversions are used. |
| F003 | `TODO` | Run final generation, tests, builds, and architecture checks. | Results meet or exceed the recorded baseline. |
| F004 | `TODO` | Review every active repository diff for generated/manual/unrelated changes. | Only scoped changes remain and user-owned work is preserved. |
| F005 | `TODO` | Prepare reviewable per-repository commits and final migration report. | Every commit has one purpose and leaves its repository buildable. |
## Execution log
Append one row whenever a task changes status. Existing rows are never rewritten, so failed or changed work remains visible.
| Time | Task | From | To | Evidence / reason |
|---|---|---|---|---|
| 2026-08-14 | S001 | `TODO` | `DONE` | Read and incorporated repository instructions and refactoring plan. |
| 2026-08-14 | S002 | `TODO` | `CHANGED` | User excluded `docs`, `DevOps`, then `ui`. |
| 2026-08-14 | S003 | `TODO` | `DONE` | Active scope reduced to five repositories. |
| 2026-08-14 | S004 | `TODO` | `DONE` | Created and checked out `feat/refactor-v1` in all active repositories. |
| 2026-08-14 | S005 | `TODO` | `DONE` | Restored excluded repositories and removed temporary branches. |
| 2026-08-14 | B001 | `TODO` | `STARTED` | Began code-backed architecture and repository audit. |
| 2026-08-14 | B001 | `STARTED` | `DONE` | Recorded repository state, actual config libraries/globals, architecture boundaries, AdminPanel writes, proto gaps, generated outputs, and plan discrepancies in `REFACTORING-AUDIT.md`. |
| 2026-08-14 | B002 | `TODO` | `STARTED` | Began read-only toolchain and dependency baseline capture. |
| 2026-08-14 | B002 | `STARTED` | `DONE` | Recorded Go, Python, uv, Django, Buf, protoc/plugin, generator, and committed dependency baselines; noted missing root proto plugins and sandbox-blocked API module metadata lookup. |
| 2026-08-14 | B003 | `TODO` | `STARTED` | Began proto lint/build/generation baseline checks with existing untracked binary protected. |
| 2026-08-14 | B003 | `STARTED` | `DONE` | Buf build/lint passed; format drift and missing root generation plugins recorded from non-mutating checks and a temporary clone. |
| 2026-08-14 | B004 | `TODO` | `STARTED` | Began auth generation, test, and build baseline. |
| 2026-08-14 | B004 | `STARTED` | `DONE` | Auth generation reproduced committed stubs; tests and build passed in a temporary clone. |
| 2026-08-14 | B005 | `TODO` | `STARTED` | Began serialized wallet generation, test, and build baseline. |
| 2026-08-14 | B005 | `STARTED` | `DONE` | Wallet generation reproduced committed stubs; tests and full build passed with no tracked diff. |
| 2026-08-14 | B006 | `TODO` | `STARTED` | Began API generation, test, Swagger, and build baseline. |
| 2026-08-14 | B006 | `STARTED` | `DONE` | API generation, tests, Swagger generation, and full build passed with reproducible outputs. |
| 2026-08-14 | B007 | `TODO` | `STARTED` | Began non-database-mutating AdminPanel system and test baseline checks. |
| 2026-08-14 | B007 | `STARTED` | `DONE` | System, compile, and migration-drift checks passed; deploy warnings and zero-test Debug Toolbar failure recorded. |
| 2026-08-14 | B008 | `TODO` | `STARTED` | Consolidated baseline results and selected the smallest compatibility-preserving first migration slice. |
| 2026-08-14 | B008 | `STARTED` | `DONE` | Locked C001 to pure koanf loader ownership plus a temporary legacy facade and synthetic tests. |
| 2026-08-14 | C001 | `TODO` | `STARTED` | Began auth config loader migration without global injection changes. |
| 2026-08-14 | C001 | `STARTED` | `DONE` | Added infrastructure-owned koanf loader, compatibility facade, and tests; generation/tests/race/build pass; committed as `29b7e07`. |
| 2026-08-14 | C002 | `TODO` | `STARTED` | Began auth global-config dependency inventory and constructor-injection migration. |
| 2026-08-14 | C002 | `STARTED` | `DONE` | Removed global config and legacy facade; injected config through auth boundaries; full verification passed; committed as `1bd5559`. |
| 2026-08-14 | C003 | `TODO` | `STARTED` | Began wallet config default/key/serve-mode compatibility inventory. |
| 2026-08-14 | C003 | `STARTED` | `DONE` | Reproduced measured fig defaults, validated all service configs, and passed generation/tests/race/build; committed as `7958530`. |
| 2026-08-14 | C004 | `TODO` | `STARTED` | Began wallet global-config dependency inventory across five modes, repositories, use cases, and Stellar adapters. |
| 2026-08-14 | C004 | `STARTED` | `CHANGED` | User prioritized a new disaster-recovery general-ledger service and wallet adapter; config injection will resume after its boundary is established. |
| 2026-08-14 | S003 | `DONE` | `CHANGED` | Added `GL` to active scope; excluded repositories remain unchanged. |
| 2026-08-14 | S004 | `DONE` | `DONE` | Created and checked out `GL/feat/refactor-v1`; all six active repositories now use the requested branch. |
| 2026-08-14 | L001 | `TODO` | `STARTED` | Began evidence-backed GL design from existing wallet transaction and Stellar paths. |
| 2026-08-14 | L001 | `STARTED` | `DONE` | Defined immutable double-entry invariants, mappings, transactional outbox delivery, controlled outage modes, and service ownership; committed in GL as `1863de1`. |
| 2026-08-14 | L002 | `TODO` | `STARTED` | Began the internal `ledger/v1` protobuf contract from the accepted GL boundary. |
| 2026-08-14 | L002 | `STARTED` | `DONE` | Added a new package without changing existing contracts; isolated-cache Buf format/lint/build checks pass; committed in proto as `b4bb506`. |
| 2026-08-14 | L003 | `TODO` | `STARTED` | Began the independent Go service scaffold and generated-consumer setup. |
| 2026-08-14 | L003 | `STARTED` | `DONE` | Scaffold generation is reproducible and tests/race/vet/build pass; committed in GL as `b1e0b01`. |
| 2026-08-14 | L004 | `TODO` | `STARTED` | Began the immutable PostgreSQL schema, decimal domain values, and transactional repository. |
| 2026-08-14 | L004 | `STARTED` | `DONE` | Domain and PostgreSQL enforce exact, balanced, sealed, immutable, idempotent journal storage; tests/race/vet/build pass; committed in GL as `0b3eaa0`. |
| 2026-08-14 | L005 | `TODO` | `STARTED` | Began application commands, persistence queries/events, reversal validation, and complete gRPC method adapters. |
| 2026-08-14 | L005 | `STARTED` | `DONE` | Added complete application/gRPC operations, exact reversal and canonical idempotency behavior, queries, error mapping, and tests; committed in GL as `76905ab`. |
| 2026-08-14 | L006 | `TODO` | `STARTED` | Began the wallet-owned ledger port, transaction mapper, generated client, and gRPC adapter. |
| 2026-08-14 | L006 | `STARTED` | `DONE` | Added the Wallet-owned ledger boundary, config, generated client, and tested gRPC adapter; full tests/race/build pass; committed in wallet as `9d91f8f`. |
| 2026-08-14 | L007 | `TODO` | `STARTED` | Began the wallet-local transactional outbox, claim/retry semantics, and dispatcher. |
| 2026-08-14 | L007 | `STARTED` | `DONE` | Added atomic enqueue, safe claiming, retry/backoff, quarantine/replay, dispatcher, and rollback/commit tests; committed in wallet as `379dbc2`. |
| 2026-08-14 | L008 | `TODO` | `STARTED` | Began per-call-site transaction-effect mapping and outbox integration. |
| 2026-08-14 | L008 | `STARTED` | `STARTED` | Checkpoint: lifecycle events now commit atomically with every transaction repository insert/update; full tests/race/build pass; committed in wallet as `ff31c87`; monetary journals remain. |
| 2026-08-14 | L008 | `STARTED` | `CHANGED` | Completed and tested all Wallet-owned financial/lifecycle paths plus dispatcher bootstrap in `d1aa339`; split AdminPanel's direct-write bypass into the already tracked `P006`/`P008` scope instead of treating it as a Wallet adapter path. |
| 2026-08-14 | I001 | `TODO` | `STARTED` | Began mapping the public buy-asset compatibility endpoints to auth publisher permissions and the existing market settlement transaction. |
| 2026-08-14 | I001 | `STARTED` | `DONE` | Recorded the additive contract, IAM role-key, publisher-order, pinned-agreement, and shared-settlement migration boundary in `REFACTORING-AUDIT.md`. |
| 2026-08-14 | I002 | `TODO` | `STARTED` | Began idempotent token-publisher bootstrap and stable IAM role-key propagation. |
| 2026-08-14 | I002 | `STARTED` | `DONE` | Added additive IAM role keys (`2d7d3ff`) and idempotent token-publisher bootstrap with focused tests (`7c3b3b6`); auth tests, race tests, and build pass. |
| 2026-08-14 | I003 | `TODO` | `STARTED` | Began additive ICO order designation, quote/settlement service contracts, and agreement-to-maker persistence linkage. |
| 2026-08-14 | I003 | `STARTED` | `DONE` | Added additive ICO order/quote/settlement fields and RPCs (`286b8e5`), role-gated hidden maker/sell orders, filtering, and agreement-to-maker persistence (`25d0f03`). |
| 2026-08-14 | I004 | `TODO` | `STARTED` | Began market-owned live publisher-order selection and BuyAsset quote delegation. |
| 2026-08-14 | I004 | `STARTED` | `DONE` | Delegated wallet quotes to market; live ICO selection verifies role, status, side, IRT pair, price, and remaining volume; agreement generation pins the maker; committed as `5a0f3d7`. |
| 2026-08-14 | I005 | `TODO` | `STARTED` | Began claim-once ICO confirmation, taker creation, and shared synchronous order settlement. |
| 2026-08-14 | I005 | `STARTED` | `DONE` | Removed the legacy direct ICO transfers; added claim-once agreement handling, taker orders, maker-wide locking/fresh reads, shared synchronous `settleOrder`, response hashes, and claim tests; committed as `ef2e4ae`. |
| 2026-08-14 | I006 | `TODO` | `STARTED` | Began focused authorization/order/claim tests, consumer regeneration, full test/race/build verification, and clean-tree review. |
| 2026-08-14 | I006 | `STARTED` | `DONE` | Verified high-volume role-gated publisher orders, IRT/side/participant constraints, overfill prevention, claim idempotency, and shared settlement; Buf checks, consumer generation, full auth/wallet/api tests, race tests, and builds pass; generated consumers committed as `a06c736`/`d2660f5`, wallet verification as `3555a5f`. |
| 2026-08-14 | I006 | `DONE` | `DONE` | Final review found the generic query's default newest-first order preceding ICO price order; replaced it with a dedicated best-price/oldest-order query and reverified tests/race/build in `0d7c820`. |
| 2026-08-14 | E001 | `TODO` | `STARTED` | Began mapping all transaction writes and the existing RabbitMQ, GL outbox, consumer, and alert paths. |
| 2026-08-14 | E001 | `STARTED` | `DONE` | Confirmed every active transaction insert/update converges in `repository/db/postgres/transaction.go`, which already atomically enqueues GL records; legacy direct AMQP publication is inactive and unsuitable for loss-free delivery. |
| 2026-08-14 | E002 | `TODO` | `STARTED` | Began the transport-neutral event envelope, per-type topic registry, transaction outbox/inbox/deadbox schema, and repository ports. |
| 2026-08-14 | E002 | `STARTED` | `DONE` | Added one stable event per transaction ID, unique topics for every transaction enum, atomic outbox enqueue, reclaimable inbox, persistent deadbox, migrations, and rollback/idempotency tests in `5dfb223`. |
| 2026-08-14 | E003 | `TODO` | `STARTED` | Began replacing the direct streadway AMQP channel with Watermill publisher/subscriber ownership and transport-neutral application ports. |
| 2026-08-14 | E003 | `STARTED` | `DONE` | Replaced the unused streadway wrapper with a shared Watermill AMQP connection, publisher/subscriber adapters, delivery confirmations, durable queues, and a retrying outbox dispatcher; full Wallet tests pass in `25fdb37`. |
| 2026-08-14 | E004 | `TODO` | `STARTED` | Began the transport-neutral transaction loader/processor boundary and idempotent inbox-backed event handler for all per-type channels. |
| 2026-08-14 | E004 | `STARTED` | `DONE` | Added topic/type validation, persisted inbox claims, duplicate-safe processing, existing processor delegation, final-status verification, claim-loss checks, and focused race coverage in `951cd02`. |
| 2026-08-14 | E005 | `TODO` | `STARTED` | Began bounded Watermill retry composition, persistent handler deadbox routing, and successful-transaction alert notification. |
| 2026-08-14 | E005 | `STARTED` | `DONE` | Added one Watermill handler per transaction topic, bounded retry/recovery, persistent deadbox-before-ack behavior, and Alert success notification without repeating completed financial effects in `c9a9101`. |
| 2026-08-14 | E006 | `TODO` | `STARTED` | Began wallet-mode-only Watermill dispatcher/router lifecycle integration, configuration defaults, graceful shutdown, and end-to-end verification. |
| 2026-08-14 | E006 | `STARTED` | `DONE` | Wired Wallet-only startup after all 17 durable subscriptions are ready, bounded handler/startup/shutdown timeouts, lazy Alert/Auth gRPC connections, graceful closure, and an in-memory dispatcher-to-router duplicate test; proto generation, full tests/race tests, vet, and build pass in `b5784b7`. |
| 2026-08-14 | T001 | `TODO` | `DONE` | Confirmed Go 1.26 is released, the official `golang:1.26-bookworm` tag exists, four active Go modules still declare 1.24, three existing Go builders already use 1.26, and GL lacks a Dockerfile. |
| 2026-08-14 | T002 | `TODO` | `STARTED` | Began the API module directive upgrade and isolated Go 1.26 verification. |
| 2026-08-14 | T002 | `STARTED` | `DONE` | Upgraded API to Go 1.26, removed behaviorally unreachable logger code exposed by vet, and passed generation, tests, vet, and build with the existing Go 1.26 Docker builder in `fb6ad38`. |
| 2026-08-14 | T003 | `TODO` | `STARTED` | Began the Auth module directive upgrade and isolated Go 1.26 verification. |
| 2026-08-14 | T003 | `STARTED` | `DONE` | Upgraded Auth to Go 1.26, removed behaviorally unreachable logger code, fixed the newsletter timeout lifecycle exposed by vet, and passed generation, tests, vet, and build in `b2d6686`. |
| 2026-08-14 | T004 | `TODO` | `STARTED` | Began the Wallet module directive upgrade and isolated Go 1.26 verification. |
| 2026-08-14 | T004 | `STARTED` | `DONE` | Upgraded Wallet to Go 1.26; module tidy and generation produced no extra drift; full tests, race tests, vet, and binary build pass in `f5243a8`. |
| 2026-08-14 | T005 | `TODO` | `STARTED` | Began the GL module upgrade and creation of its missing Go 1.26 multi-stage Dockerfile. |
| 2026-08-14 | T005 | `STARTED` | `CHANGED` | Separate GL explorer/web changes appeared during verification; preserved them and isolated the Go directive/Dockerfile commit from that work. |
| 2026-08-14 | T007 | `TODO` | `STARTED` | User required `HTTP_PROXY` and `HTTPS_PROXY` unset for `go get` and selected `https://go.reg.darano.ir` as the Go proxy. |
| 2026-08-14 | T007 | `STARTED` | `DONE` | Updated all four Go Docker proxy defaults in per-repository commits and passed Dockerfile checks; cold API build exposed delayed 404 coverage gaps in the selected proxy, so no fallback was introduced. |
| 2026-08-14 | T005 | `CHANGED` | `DONE` | Committed the isolated GL Go 1.26 directive and new multi-stage Dockerfile as `ce5f8b4`; current working directive remains 1.26 while unrelated explorer/dependency changes stay uncommitted. |
| 2026-08-14 | T006 | `TODO` | `STARTED` | Began final branch, module directive, Docker builder, proxy, and worktree audit across active repositories. |
| 2026-08-14 | T006 | `STARTED` | `DONE` | Confirmed all Go modules/builders use 1.26, all Go builders use the Darano proxy, all active branches are correct, and user-owned proto/GL work remains untouched. |
| 2026-08-14 | T008 | `TODO` | `STARTED` | Began sequential full image builds for API, Auth, Wallet, and GL using the configured Darano Go proxy. |
| 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 | `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. |
+65
View File
@@ -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`.
+28
View File
@@ -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.
+28
View File
@@ -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.
+38
View File
@@ -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.
+45
View File
@@ -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.
+22
View File
@@ -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.
+18
View File
@@ -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.
+24
View File
@@ -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`.
+47
View File
@@ -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
```
@@ -0,0 +1,327 @@
# گزارش فنی زیرساخت سامانه توکن‌سازی دارانو
**تهیه‌کننده:** شرکت توسعه راه‌کارهای نامتمرکز سنا
**تاریخ انتشار:** مرداد ۱۴۰۴
**نسخه:** ۱.۰
---
## ۱. معرفی پروژه
### ۱.۱ درباره شرکت
شرکت **توسعه راه‌کارهای نامتمرکز سنا** فعال در حوزه فناوری بلاکچین و توکن‌سازی دارایی‌های واقعی (RWA — Real World Assets) است. مأموریت اصلی این شرکت، ایجاد زیرساخت‌های لازم برای تبدیل دارایی‌های فیزیکی و حقوقی به توکن‌های قابل معامله در بازارهای دیجیتال، با رعایت کامل الزامات رگولاتوری و قوانین بانک مرکزی جمهوری اسلامی ایران است.
### ۱.۲ معرفی سامانه دارانو
سامانه **دارانو** پلتفرمی برای **توکن‌سازی دارایی‌های واقعی** است. این سامانه دارایی‌های فیزیکی (مانند املاک و مستغلات) را پس از طی فرآیندهای احراز مالکیت، ارزیابی و تکمیل تشریفات حقوقی، به توکن‌های دیجیتال تبدیل می‌کند. هر توکن نماینده بخشی از مالکیت دارایی پایه بوده و امکان خرید، فروش و معامله در بازار اولیه و ثانویه را فراهم می‌سازد.
در فاز پایلوت، تمرکز سامانه بر روی **املاک** است و یک واحد ملکی با نام **«مژگان»** به‌عنوان نمونه اولیه توکن‌سازی انتخاب شده است.
### ۱.۳ اصول حاکم بر سامانه
| اصل | توضیح |
|-----|--------|
| **رعایت رگولاتوری** | کلیه فرآیندها منطبق بر قوانین بانک مرکزی و مقررات مرتبط طراحی شده‌اند |
| **بلاکچین به عنوان Source of Truth** | مالکیت توکن‌ها فقط و فقط روی شبکه ققنوس ثبت می‌شود |
| **تفکیک نقش‌ها** | ناشر، میزبان، سرمایه‌گذار، بازارگردان و ناظر هر کدام نقش مشخصی دارند |
| **امنیت چندلایه** | لایه‌های امنیتی از Cloudflare تا مدیریت کلیدها |
| **شفافیت کامل** | تمامی تراکنش‌ها و وضعیت دارایی‌ها شفاف و قابل ردیابی است |
---
## ۲. شرح پروژه
### ۲.۱ فرآیند توکن‌سازی
فرآیند توکن‌سازی در دارانو شامل مراحل زیر است:
```mermaid
flowchart LR
A[۱. شناسایی و ارزیابی دارایی] --> B[۲. بررسی حقوقی و مالکیت]
B --> C[۳. قرارداد میزبانی و امانت]
C --> D[۴. انتشار توکن روی ققنوس]
D --> E[۵. عرضه در بازار اولیه]
E --> F[۶. معامله در بازار ثانویه]
F --> G[۷. توزیع درآمد دوره‌ای]
```
### ۲.۲ جریان درآمدی دارایی
درآمدهای حاصل از دارایی پایه (مانند اجاره‌بها) از طریق مکانیزم‌های مختلف میان دارندگان توکن توزیع می‌شود:
- **توزیع مستقیم ریالی:** محاسبه ضریب توزیع بر اساس نسبت توکن‌های فروخته‌شده به کل توکن‌ها
- **بازخرید توکن از طریق بازارگردان:** ایجاد فشار خرید و رشد قیمت توکن
- **سبدگردانی و اثر مرکب:** امکان سرمایه‌گذاری مجدد سود برای دارندگان توکن
---
## ۳. کاربران هدف
سیستم دارانو شامل نقش‌های زیر می‌باشد:
| نقش | شرح | دسترسی |
|-----|-----|--------|
| **سرمایه‌گذار (خریدار)** | کاربران عادی که توکن‌ها را خریداری و نگهداری می‌کنند | خرید توکن، معامله در بازار ثانویه، مشاهده پورتفولیو |
| **ناشر** | مالک اصلی دارایی (یا صاحب سببی مانند صلح‌نامه/وکالت‌نامه) | ایجاد پروژه توکن‌سازی، ثبت اطلاعات دارایی |
| **میزبان (امین دارایی)** | نهاد مسئول نگهداری فیزیکی و حقوقی دارایی | تأیید وضعیت دارایی، همکاری حقوقی |
| **تیم بازارگردان** | یک یا چند نفر مسئول تنظیم و مدیریت بازار ثانویه | مدیریت نقدینگی، تسهیل معاملات |
| **پلتفرم (ادمین)** | تیم سنا مستقر در سامانه — شامل تیم فنی، پشتیبانی و مدیر سامانه | مدیریت کاربران، صدور توکن، پیکربندی سیستم |
| **بازرس بانکی** | کارشناس منتخب بانک برای نظارت امنیتی و بازرسی دفتری | مشاهده تراکنش‌ها، تیک امنیتی، نظارت بر حساب‌وکتاب |
> **نکته:** سامانه اپراتور عمومی ندارد و تنها چند ادمین اصلی با دسترسی‌های مجزا فعالیت می‌کنند. مدیر سامانه دسترسی به ایجاد توکن جدید و تغییرات سایت دارد. تیم توسعه به کدها و اجرای آن‌ها روی سرور تست و سندباکس دسترسی دارد، اما استقرار در محیط عملیاتی (Production) نیازمند تأیید مدیر سامانه و کمیته اجرایی است.
---
## ۴. ارتباط سامانه با بیرون
### ۴.۱ معماری ارتباطی
```mermaid
flowchart LR
subgraph External
CDN[CDN / Cloudflare]
Firewall[فایروال لینوکس]
end
subgraph Darano
Traefik[Traefik<br/>Reverse Proxy]
API[API Gateway]
Services[سرویس‌های داخلی]
end
Internet[(اینترنت)] --> CDN --> Firewall --> Traefik --> API --> Services
style CDN fill:#e1f5fe
style Firewall fill:#fff3e0
style Traefik fill:#e8f5e9
```
- **لایه CDN:** ترافیک ورودی ابتدا از CDN عبور می‌کند (پشتیبانی از DDoS Protection و TLS/SSL)
- **فایروال:** در حال حاضر از فایروال لینوکس (Firewalld) استفاده می‌شود؛ در آینده قرار است سرورها پشت CDN اصلی قرار گیرند
- **Traefik:** نقش Reverse Proxy و مدیریت ترافیک داخلی
- **API Gateway:** نقطه ورود واحد برای تمام درخواست‌های API
### ۴.۲ ارتباط با شبکه ققنوس
سامانه برای ثبت تراکنش‌های توکنی از **شبکه ققنوس** (بر پایه استلار) استفاده می‌کند. بانک ملت نیز یکی از میزبان‌های این شبکه است. ارتباط از طریق Horizon API انجام شده و یک سرویس **Wallet Streamer** به‌صورت مداوم تراکنش‌های شبکه را رصد و با سیستم داخلی همگام‌سازی می‌کند.
---
## ۵. دیاگرام موارد استفاده (Use Case Diagram)
```mermaid
graph TB
Investor[سرمایه‌گذار]
Issuer[ناشر]
Custodian[میزبان/امین دارایی]
MarketMaker[بازارگردان]
PlatformAdmin[ادمین پلتفرم]
BankInspector[بازرس بانکی]
Investor --> UC1[ثبت‌نام و ورود]
Investor --> UC2[احراز هویت KYC]
Investor --> UC3[خرید توکن در بازار اولیه]
Investor --> UC4[معامله در بازار ثانویه]
Investor --> UC5[مشاهده پورتفولیو و تاریخچه]
Investor --> UC6[واریز و برداشت ریال]
Investor --> UC7[واریز و برداشت توکن]
Issuer --> UC8[ایجاد پروژه توکن‌سازی]
Issuer --> UC9[ثبت اطلاعات دارایی]
Custodian --> UC10[تأیید وضعیت دارایی]
Custodian --> UC11[همکاری حقوقی]
MarketMaker --> UC12[مدیریت نقدینگی بازار]
MarketMaker --> UC13[سفارش‌گذاری در بازار ثانویه]
PlatformAdmin --> UC14[مدیریت کاربران]
PlatformAdmin --> UC15[صدور و مدیریت توکن]
PlatformAdmin --> UC16[مدیریت سفارش‌ها و بازار]
PlatformAdmin --> UC17[مدیریت بازخرید]
PlatformAdmin --> UC18[پیکربندی و پایش سامانه]
BankInspector --> UC19[مشاهده تراکنش‌ها]
BankInspector --> UC20[تیک امنیتی و نظارت]
style Investor fill:#e3f2fd
style Issuer fill:#f3e5f5
style Custodian fill:#e8f5e9
style MarketMaker fill:#fff3e0
style PlatformAdmin fill:#fce4ec
style BankInspector fill:#efebe9
```
---
## ۶. سرویس‌های شخص ثالث (3rd Party)
### ۶.۱ خدمات احراز هویت و بانکی
| سرویس | نقش | توضیح |
|-------|------|--------|
| **سامانه شاهکار** | احراز مالکیت سیم‌کارت و مطابقت کدملی با شماره تماس | استعلام از پایگاه داده پست |
| **سامانه احراز هویت** | تأیید اطلاعات هویتی (کدملی، تاریخ تولد، تصویر) | سرویس‌های شخص ثالث مشابه (مانند زحل، احراز، جیبیت) |
| **استعلامات بانکی** | تأیید مالکیت حساب بانکی و شماره شبا | سرویس‌های مشابه |
### ۶.۲ خدمات ارتباطی
| سرویس | نقش | توضیح |
|-------|------|--------|
| **پنل ایمیل سازمانی** | ارسال ایمیل‌های خدماتی (خوش‌آمدگویی، تأیید تراکنش و …) | سرویس‌هایی مشابه لیموهاست |
| **پنل پیامک** | ارسال OTP و پیام‌های خدماتی | سرویس‌هایی مشابه کاوه‌نگار |
### ۶.۳ زیرساخت و مانیتورینگ
| سرویس | نقش | توضیح |
|-------|------|--------|
| **Prometheus** | جمع‌آوری متریک‌ها | استاندارد CNCF |
| **Grafana** | داشبورد و تجسم داده‌ها | استاندارد CNCF |
| **OpenTelemetry** | Observability یکپارچه | استاندارد CNCF |
| **Node Exporter / cAdvisor** | مانیتورینگ سیستم‌عامل و کانتینرها | استاندارد CNCF |
| **S3 / Object Storage** | ذخیره‌سازی فایل‌ها و بک‌آپ | سرویس ابری |
| **Traefik** | Reverse Proxy و Load Balancer | استاندارد CNCF |
| **مرورگر شبکه (Stellar Horizon)** | ارتباط با شبکه ققنوس | سرویس بلاکچین |
---
## ۷. زیرساخت پلتفرم
### ۷.۱ زیرساخت فعلی
```mermaid
flowchart TB
subgraph InternetLayer
CDN[CDN / Cloudflare]
Firewall[Firewalld]
end
subgraph VPSLayer["زیرساخت ابری مورد تایید بانک"]
Docker[Docker + Docker Compose]
subgraph Services
Traefik[Traefik<br/>Reverse Proxy]
UI[UI - Next.js]
Admin[Django Admin]
API[API Gateway - Go]
Auth[Auth Service - Go]
Wallet[Wallet Service - Go]
Market[Market Service - Go]
Streamer[Wallet Streamer - Go]
end
subgraph Data
DB[(PostgreSQL)]
Cache[(Redis)]
MQ[(RabbitMQ)]
end
end
subgraph BlockchainLayer
Ghoghnos[(شبکه ققنوس<br/>بر پایه استلار)]
end
subgraph Monitoring
Prometheus[Prometheus<br/>سرور جداگانه]
Grafana[Grafana]
Alertmanager[Alertmanager]
end
CDN --> Firewall --> Traefik
Traefik --> UI
Traefik --> Admin
Traefik --> API
API --> Auth
API --> Wallet
API --> Market
Auth --> DB
Auth --> Cache
Wallet --> DB
Wallet --> Cache
Market --> DB
Market --> Cache
Market --> MQ
Streamer --> DB
Streamer --> MQ
Wallet --> Ghoghnos
Streamer --> Ghoghnos
Prometheus --> API
Prometheus --> Auth
Prometheus --> Wallet
Prometheus --> Market
Prometheus --> DB
Grafana --> Prometheus
Alertmanager --> Prometheus
```
**مشخصات فنی زیرساخت فعلی:**
| لایه | فناوری | توضیح |
|------|--------|--------|
| میزبانی | سرویس ابری مورد تایید بانک | VPS با گواهی امنیتی بانکی |
| کانتینری‌سازی | Docker + Docker Compose | ایزولاسیون کامل سرویس‌ها |
| Reverse Proxy | Traefik v2.10 | مدیریت TLS و Routing |
| API Gateway | Go + Gin Router | مسیریابی، احراز هویت، Rate Limiting |
| سرویس‌های بیزینس | Go (GORM, Stellar SDK) | Auth, Wallet, Market |
| پنل مدیریت | Python + Django | Server-Side Rendering |
| رابط کاربری | Next.js + React | SSR + Client Rendering |
| پایگاه داده | PostgreSQL 15 | داده‌های رابطه‌ای اصلی |
| کش / Session | Redis 7 | Session، Rate Limit، Cache |
| صف پیام | RabbitMQ 3.12 | Event-Driven آینده |
| مانیتورینگ | Prometheus + Grafana + OpenTelemetry | سرور مانیتورینگ جداگانه |
### ۷.۲ زیرساخت آینده (Roadmap)
```mermaid
flowchart LR
subgraph Current["زیرساخت فعلی (Sync)"]
API --> Auth
API --> Wallet
API --> Market
Market --> Wallet
end
subgraph Future["زیرساخت آینده (Event-Driven)"]
API --> Auth
API --> Wallet
API --> Market
EventBus[(Event Bus<br/>Kafka / RabbitMQ)]
Auth -.->|Events| EventBus
Wallet -.->|Events| EventBus
Market -.->|Events| EventBus
Streamer -.->|Events| EventBus
EventBus --> Notification[Notification Service]
EventBus --> Analytics[Analytics Service]
EventBus --> Audit[Audit Service]
end
style Current fill:#e3f2fd
style Future fill:#e8f5e9
```
| ویژگی | وضعیت فعلی | هدف آینده |
|-------|-----------|-----------|
| الگوی ارتباطی | Synchronous (REST/gRPC) | Event-Driven (Kafka/RabbitMQ) |
| مقیاس‌پذیری | Docker Compose + Horizontal Scaling | Kubernetes (K8s) |
| Event Bus | محدود (فقط RabbitMQ در Wallet) | Event Bus مرکزی با Kafka |
| مدیریت کلیدها | Secret Manager در Git | HashiCorp Vault / AWS KMS |
| CI/CD | GitHub Actions | Pipeline خودکار با تأیید دو مرحله‌ای |
| Service Mesh | ندارد | Istio یا Linkerd |
| Database | PostgreSQL Single | Master-Slave + Read Replicas |
---
## ۸. خلاصه و جمع‌بندی
سامانه دارانو، توسعه‌یافته توسط شرکت توسعه راه‌کارهای نامتمرکز سنا، یک پلتفرم توکن‌سازی دارایی‌های واقعی است که با رعایت کامل ضوابط رگولاتوری و قوانین بانک مرکزی طراحی و پیاده‌سازی شده است. معماری سامانه بر پایه **میکروسرویس**، **بلاکچین ققنوس به عنوان Source of Truth** و **زیرساخت ابری مورد تایید بانک** بنا شده و از خدمات شخص ثالث معتبر برای احراز هویت، ارتباطات و مانیتورینگ بهره می‌برد.
نقاط قوت کلیدی سامانه:
- **امنیت بالا:** مدیریت کلیدها با Secret Manager، احراز هویت چندمرحله‌ای، فایروال و CDN
- **شفافیت:** مالکیت توکن‌ها فقط روی بلاکچین، ردیابی کامل تراکنش‌ها
- **مقیاس‌پذیری:** معماری میکروسرویس با امکان مهاجرت به Event-Driven و Kubernetes
- **نظارت:** مانیتورینگ ۲۴/۷ با ابزارهای استاندارد CNCF و دسترسی بازرس بانکی