docs: capture refactor workflow and project memory
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
# Darano project memory
|
||||
|
||||
Updated: 2026-08-29
|
||||
|
||||
## 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.
|
||||
@@ -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.
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
# Darano discovery progress
|
||||
|
||||
Updated: 2026-08-28 (Asia/Tehran)
|
||||
|
||||
## Step 1 — workspace inventory
|
||||
|
||||
- The workspace is an aggregate of independent repositories: `api`, `auth`, `wallet`, `GL`, `ui`, `AdminPanel`, `proto`, `DevOps`, `docs`, `alert`, and Kuknos node scripts.
|
||||
- `api` is the public REST gateway; Go backends communicate over gRPC. The customer UI is Next.js. The admin surface is Django and currently has direct database access.
|
||||
- Prior-machine planning and refactoring records are present in `dev-procfile/`. They include completed work on a transactional outbox and event-driven wallet transaction processing, plus unfinished GL and admin-integration work.
|
||||
- Repository-specific instructions were read before analysis. Existing user changes will be preserved.
|
||||
|
||||
## Next checks
|
||||
|
||||
- Reconcile TODO claims with current code and Git history.
|
||||
- Trace business domains and every user transaction entry point through settlement.
|
||||
- Audit GL capabilities and the Kuknos/GL source-of-truth switch.
|
||||
- Run and assess relevant test suites.
|
||||
- Compare the staging product with the implemented UI/API where access permits.
|
||||
- Produce the final concise report and mind map in this directory.
|
||||
|
||||
## Current limitation
|
||||
|
||||
- The interactive browser surface is unavailable in this session. Staging-site inspection will use read-only web access; any authenticated-only behavior may require user-provided access or screenshots.
|
||||
|
||||
## Step 2 — recovered-work reconciliation
|
||||
|
||||
- The tracker is internally consistent with Git history for `wallet`, `auth`, and `proto`: their refactor branches contain the cited commits.
|
||||
- The local `GL` checkout is misleadingly on `main` (initial README/license only). The complete GL implementation and explorer are present, identically, on `origin/dev` and `origin/feat/refactor-v1` at `32e7b6b`.
|
||||
- The root `Procfile` does not start GL or its explorer, and the checked-in stage compose/config does not deploy or configure GL. Therefore “start the main app and write alongside Stellar” is not true for the current aggregate startup/deployment despite the service and wallet adapters existing on feature branches.
|
||||
- The accepted GL design deliberately excludes automatic failover. It defines `MIRROR`, future admin-authorized `DEGRADED_LEDGER`, and `RECONCILE`, but only mirror recording is implemented so far.
|
||||
- The event pipeline is real code, not merely a plan: transaction persistence atomically creates a per-type outbox event; Watermill/RabbitMQ dispatches it; an idempotent inbox handler runs the legacy processor; retries and deadbox handling exist. It starts only in wallet service mode.
|
||||
|
||||
## Early risks to verify
|
||||
|
||||
- GL journals currently originate from Wallet `float64` amounts formatted to seven decimal places; GL itself correctly expects fixed-point decimal strings. This boundary can preserve pre-existing rounding error and is weaker than the stated `numeric(38,18)` invariant.
|
||||
- Transaction lifecycle event version is hard-coded to `1`, while the idempotency key hashes the payload. Multiple state changes for one transaction may conflict with GL's unique source-transaction/event-version constraint; this needs a test/code-path check.
|
||||
- The transaction-event consumer reports success alerts even when it receives a duplicate event for a transaction already marked successful. Inbox idempotency prevents repeat handling after a succeeded inbox claim, but crash windows around notification vs. inbox completion need review.
|
||||
|
||||
## Step 3 — staging-flow reconciliation
|
||||
|
||||
- User screenshots confirm available/locked/total balances, asset actions, transaction history, market maker/taker purchase, ICO purchase from a selected maker, legal agreement acceptance, verified Sheba accounts, IRT withdrawal, and referrals.
|
||||
- Product clarification adds five required workflows: Kuknos subscription, bank-deposit ingestion, IPG confirmation, admin-approved IRT withdrawal, and third-party collateral locks.
|
||||
- Every transaction may require SMS, TOTP, or email 2FA plus a versioned agreement/contract/policy acceptance. These are prerequisites and immutable audit evidence, not incidental UI steps.
|
||||
- GL was switched from `main` to the canonical `feat/refactor-v1` branch. Its tracked license was restored after a checkout filesystem anomaly; the pre-existing `.DS_Store` was preserved.
|
||||
|
||||
## Step 4 — availability policy
|
||||
|
||||
- GL is confirmed as a mandatory transaction dependency. There is no GL operational failover mode: GL failure must halt every value-changing workflow until recovery.
|
||||
- `/health` must become critical/not-ready and the incident/recovery transitions must be reported through OpenTelemetry logs (with metrics/traces recommended for correlation).
|
||||
- Current behavior violates this policy: Wallet health is unconditional success, GL remains `Serving=true` when its database ping fails, API health does not aggregate GL, and the asynchronous ledger dispatcher only logs/retries while transactions continue.
|
||||
- Automatic acceptance policy for third-party collateral transactions is out of scope and retained as a future feature.
|
||||
|
||||
## Step 5 — authority and Kuknos mode
|
||||
|
||||
- GL is the primary append-only financial source of truth. Kuknos is the secondary settlement and verification source.
|
||||
- Normal operation requires both. GL outage always halts transactions. Kuknos outage also halts transactions until an authorized operator explicitly enables GL-only `KUKNOS_DISABLED` mode through AdminPanel or configuration.
|
||||
- The mode may not switch automatically. Its actor, reason, time, previous/new state, and recovery/reconciliation must be auditable and sent through OpenTelemetry.
|
||||
- Append-only enforcement is present in GL database triggers and reversal validation.
|
||||
|
||||
## Step 6 — implementation
|
||||
|
||||
- Implemented the GL/Kuknos fail-closed gate at mutation RPC, transaction worker, health, and Kuknos subscription boundaries.
|
||||
- Added the explicit configuration switch `network.kuknos-enabled`; no automatic switch or automatic acceptance policy was added.
|
||||
- Corrected GL database readiness, API HTTP 503 health propagation, and structured OTel-compatible incident/recovery logs.
|
||||
- Wallet and GL full test suites pass. Details and remaining atomicity/deployment limits are in `05-availability-implementation.md`.
|
||||
@@ -0,0 +1,28 @@
|
||||
# Project index
|
||||
|
||||
| Repository | Purpose | Main domain |
|
||||
|---|---|---|
|
||||
| `ui` | Next.js customer site and dashboard | onboarding, assets, buy/redeem, market, history |
|
||||
| `api` | Only public HTTP gateway; translates REST to gRPC | API/auth boundary |
|
||||
| `auth` | OTP, JWT, TFA, identity, bank info, roles/permissions | identity and access |
|
||||
| `wallet` | Wallet, asset, transaction, market, IPG, BNPL, redeem, alert workers | financial orchestration |
|
||||
| `GL` | Append-only double-entry ledger and explorer | backup financial truth |
|
||||
| `AdminPanel` | Django operations console with direct shared-DB access | manual administration |
|
||||
| `proto` | Versioned gRPC contracts | service boundary |
|
||||
| `DevOps` | Compose, Traefik, databases, Redis, RabbitMQ, MinIO, monitoring | runtime platform |
|
||||
| `Kuknos-Node-scripts` | Kuknos/Stellar node operations | blockchain infrastructure |
|
||||
| `docs` | Product documentation | documentation |
|
||||
| `alert` | Legacy/minimal alert repository; active alert server is in Wallet | notifications |
|
||||
|
||||
## Runtime shape
|
||||
|
||||
`Browser -> UI -> API -> Auth / Wallet / Market / Alert`
|
||||
|
||||
Wallet uses PostgreSQL and Redis, submits blockchain work through the Stellar-compatible Kuknos adapter, and publishes durable transaction events through RabbitMQ. Wallet also has a separate durable outbox that mirrors lifecycle events and successful monetary effects to GL.
|
||||
|
||||
## Branch reality
|
||||
|
||||
- Refactor code is active in `wallet`, `auth`, `proto`, and `AdminPanel` feature branches.
|
||||
- Full GL code is now checked out on `GL/feat/refactor-v1`, tracking `origin/feat/refactor-v1`.
|
||||
- `api` and `dev-procfile` have no local or remote `feat/refactor-v1` ref in this checkout; both remain on `main` rather than inventing an untracked branch lineage.
|
||||
- Stage compose currently deploys API/Auth/Wallet/Admin/UI, but not GL or the GL explorer.
|
||||
@@ -0,0 +1,28 @@
|
||||
# Business-domain map
|
||||
|
||||
## Core domains
|
||||
|
||||
- Tokenization: asset definition, issuer/network metadata, price, supply/buy limits, policy, whitelist, and publisher-owned ICO sell orders.
|
||||
- Custody and settlement: user wallets, Kuknos trustlines, internal/external transfer, deposit/withdrawal, balance locks, commissions, and blockchain tracking.
|
||||
- Primary sale: quote -> agreement -> claim-once acceptance -> taker order -> settlement against the authorized token publisher's live maker order.
|
||||
- Secondary market: buy/sell orders, contracts, matching/settlement, cancellation, history, and market clearing.
|
||||
- Fiat rails: Mellat IPG deposit confirmation, IRT withdrawal approval, accounting and withdrawal logs.
|
||||
- Redemption: token return, repayment calculation, bank destination, and operational payout record.
|
||||
- IAM/compliance: OTP/JWT/TFA, identity/KYC data, bank accounts, roles, route permissions, and asset-level admin permissions.
|
||||
- Financing: BNPL plans, applications, companies, schedules, supported assets, and locked balances.
|
||||
- Audit/accounting: Wallet transaction lifecycle, immutable GL journals/events, balances, replay, and explorer.
|
||||
- Legal evidence: versioned agreements/contracts/policies, acceptance, signer, 2FA proof, and transaction linkage.
|
||||
- Collateral authorization: third-party API clients, scoped lock requests, approval/denial, reservation, release, and consumption.
|
||||
|
||||
## Key invariants already expressed
|
||||
|
||||
- GL monetary journals are immutable, atomic, idempotent, fixed-point, and balanced per asset.
|
||||
- A primary-sale maker must be an open ICO sell order owned by a user with the stable `token-publisher` role.
|
||||
- Agreement acceptance is claim-once; settlement rechecks price, commission, order status, and remaining volume.
|
||||
- Transaction inserts and GL/event outbox writes share the Wallet database transaction.
|
||||
- A market/ICO operation must reserve spend and inventory before asynchronous execution; rejection or failure must release the same reservation exactly once.
|
||||
- IRT withdrawal is a stateful approval workflow, not a direct transfer: request -> freeze -> admin decision -> settle/release.
|
||||
|
||||
## Ownership problem
|
||||
|
||||
AdminPanel can still mutate unmanaged replicas of core tables directly. These writes bypass Wallet validation, Kuknos operations, transaction events, and GL recording. Until mutations go through authenticated internal RPCs and legacy models become read-only, the business invariants are not system-wide.
|
||||
@@ -0,0 +1,38 @@
|
||||
# Event, GL, and test audit
|
||||
|
||||
## User transaction events
|
||||
|
||||
Status: partially correct, not reliable enough yet.
|
||||
|
||||
- Good: each transaction insert atomically creates a durable RabbitMQ outbox record; delivery has retries/deadbox; consumption has an idempotent inbox.
|
||||
- Critical: the event is created only once, at initial insert. Transfers and redeem are inserted as `CREATED`; if consumed before confirmation, the handler rejects/retries and can dead-letter. Later status updates do not refresh/re-enqueue it because transaction ID and payload are immutable.
|
||||
- Only `BUY`, `SELL`, `INTERNAL_TRANSFER`, and `REDEEM` are executable by the event processor. Other declared topics—including IRT deposit/withdrawal, external transfer, commission, lock, and trustline—cannot be processed by it.
|
||||
- Several user flows still execute synchronously: external Kuknos transfers, Mellat/IPG steps, IRT withdrawal, and ICO/market settlement. The current pipeline therefore does not satisfy “user-side transaction requests are event driven” as a general invariant.
|
||||
|
||||
Recommended contract: persist a command/request event only after validation and TFA, use a unique command ID plus state/version, let a worker own side effects, and expose request status to the client. Lifecycle events should be separate facts, not reuse a single immutable command row.
|
||||
|
||||
The clarified product flows require separate event-driven process managers for market/ICO settlement, Kuknos ingestion, bank/IPG deposits, IRT withdrawal approval, and third-party collateral locks. Each must persist 2FA and agreement evidence before emitting an executable command.
|
||||
|
||||
## GL
|
||||
|
||||
Status: primary append-only source of truth; current integration still behaves as an asynchronous mirror.
|
||||
|
||||
- The feature branch implements double-entry journals, lifecycle events, idempotency, immutable PostgreSQL storage, balance queries, replay, and a localized explorer.
|
||||
- Required availability policy: fail closed. When GL or its database is unhealthy, reject/pause all new value-changing commands and pause transaction workers until GL recovers. Reads may remain available but `/health` must report `CRITICAL`/not-ready.
|
||||
- Normal mode requires both GL and Kuknos. Kuknos is the secondary settlement/verification truth. Its outage also halts transactions unless an operator explicitly activates `KUKNOS_DISABLED` through AdminPanel or configuration.
|
||||
- `KUKNOS_DISABLED` must never activate automatically. Mode changes require authorization, immutable audit evidence, OTel telemetry, and reconciliation before/after returning to normal.
|
||||
- Implemented: shared readiness gate at Wallet/Internal/Market mutation RPCs and transaction workers; GL database-aware health; API critical/503 propagation; structured OTel-compatible transition logs; config-only Kuknos switch; local/config wiring.
|
||||
- Still missing: persisted/AdminPanel mode control, hysteresis, metrics/traces, concrete compose GL deployment, reconciliation tooling, broad outage/concurrency acceptance tests, trustline state, and reservation ownership/reason semantics.
|
||||
- Health polling alone has a race: GL can fail after the check but before a Wallet commit or external Kuknos/IPG submission. A strict “no transaction commits while GL is unavailable” guarantee requires an acknowledged GL write/prepare step or a formal saga; an asynchronous outbox plus preflight check cannot provide that guarantee by itself.
|
||||
- Money risk: Wallet stores and maps `float64`, then formats only seven decimal places before GL. GL's `numeric(38,18)` cannot recover precision already lost upstream.
|
||||
- Lifecycle risk: GL event version is always `1`; multiple transaction states may collide at the GL uniqueness boundary.
|
||||
- Append-only verification: PostgreSQL triggers reject journal deletion, entry/account/event update or deletion, and entry insertion after journal sealing. Corrections are exact reversing journals; the original record remains intact.
|
||||
|
||||
## Tests run on 2026-08-28
|
||||
|
||||
- GL feature branch in isolated copy: `go test ./...` passed.
|
||||
- Wallet: full `go test ./...` passes after replacing the invalid dependency on ignored secret config fixtures with explicit default/override tests.
|
||||
- API: health tests pass in an isolated copy populated with compatible generated stubs; the checkout still needs its normal `buf generate` step. Auth was not changed.
|
||||
- Coverage gap: most `core/walletImp` user flows have no package tests. Existing event tests prove infrastructure mechanics but miss the `CREATED -> confirmed -> PENDING_TRX` race described above.
|
||||
|
||||
Minimum logical acceptance tests: GL-down admission rejection, workers paused while GL is critical, recovery without duplicate execution, failure between health check and commit, duplicate commands, broker/Kuknos/IPG outage, crash after external submission, state-version ordering, concurrent spend/lock, partial maker fills, whitelist rejection, amount precision, 2FA/agreement evidence, admin approve/deny, reconciliation, and a full request-to-final-status test for every transaction type.
|
||||
@@ -0,0 +1,45 @@
|
||||
# Product flows confirmed from staging screenshots
|
||||
|
||||
## Wallet and balances
|
||||
|
||||
- Portfolio shows total value, available value, locked value, per-asset balance/value/price, and allowed actions.
|
||||
- “Locked” is a first-class user-visible balance. GL must expose at least `available`, `locked`, and `total = available + locked` per user/asset, with the lock reason and owning operation.
|
||||
- History exposes asset, time, amount, transaction type, state, tracking number, and Kuknos/hash-like reference.
|
||||
|
||||
## Transaction gate
|
||||
|
||||
Every value-changing request can require configurable 2FA (`SMS`, `TOTP`, or `EMAIL`) and an agreement acceptance. An agreement may be:
|
||||
|
||||
- a generated legal contract;
|
||||
- transaction-specific terms and conditions; or
|
||||
- acceptance of site/platform policy.
|
||||
|
||||
The accepted agreement version, content hash, actor, transaction/request ID, timestamp, and 2FA method/result must be immutable audit evidence.
|
||||
|
||||
## Trade and ICO
|
||||
|
||||
- Secondary market: maker posts an order; taker accepts all or part of its remaining quantity. Contract acceptance precedes settlement.
|
||||
- ICO: taker buys only from a specific authorized publisher maker order. Asset/user whitelisting may reject the request before agreement/settlement.
|
||||
- Reserved quantities and balances must be locked atomically when an order/request becomes executable, then consumed or released exactly once.
|
||||
|
||||
## Money movement
|
||||
|
||||
- Kuknos subscription imports observed blockchain transactions/deposits.
|
||||
- External bank deposit causes IRT issuance/transfer from the server treasury to the user.
|
||||
- IPG flow: create gateway token -> redirect -> confirm callback -> transfer IRT from treasury.
|
||||
- IRT withdrawal: create request -> freeze IRT -> 2FA/agreement if required -> admin approve/deny -> finalize state and consume/release lock.
|
||||
- Authorized third party: API-token request -> manual/user/admin decision -> lock asset as collateral -> success, denied, or failed result; later release/consume must reference the original lock. Automatic acceptance policy is explicitly a future feature.
|
||||
|
||||
## Platform availability rule
|
||||
|
||||
- GL is the primary, append-only source of truth and is mandatory for every value-changing workflow.
|
||||
- Kuknos is the secondary settlement/verification source of truth. `NORMAL` mode requires both GL and Kuknos.
|
||||
- GL/GL-database failure puts transaction admission and transaction workers into a fail-closed halt until health is restored.
|
||||
- Kuknos failure also halts transactions unless an authorized operator explicitly selects `KUKNOS_DISABLED` using AdminPanel or configuration. There is no automatic switch.
|
||||
- Public health must expose the incident as critical/not-ready, and transitions into, during, and out of the incident must be observable through OpenTelemetry.
|
||||
- Non-mutating views can remain available if their data can be labelled consistently and safely.
|
||||
|
||||
## Bank and referral
|
||||
|
||||
- Bank information maintains verified Sheba/IBAN accounts; the account must belong to the identified user before withdrawal.
|
||||
- Referral tracks invitation code/link, referred users, commission share, received/withdrawable reward, and reward withdrawal.
|
||||
@@ -0,0 +1,22 @@
|
||||
# Availability implementation
|
||||
|
||||
Implemented on `feat/refactor-v1` on 2026-08-28.
|
||||
|
||||
- Added one fail-closed financial availability gate shared by Wallet, Internal Wallet, Market, and transaction workers.
|
||||
- Normal mode requires healthy GL (including its database) and Kuknos Horizon. `network.kuknos-enabled=false` is the explicit, startup-time GL-only switch; it never changes automatically.
|
||||
- Mutation RPCs return gRPC `UNAVAILABLE` during an outage. Read-only RPCs remain available; unknown future RPCs are treated as mutations.
|
||||
- Transaction event outbox/inbox workers pause before claiming work. Dependency outages do not dead-letter business events.
|
||||
- Kuknos subscription blocks its callback during a GL outage so the Horizon cursor cannot advance past an unrecorded external deposit; the streamer pauses entirely when Kuknos is manually disabled.
|
||||
- GL health now reports not-serving when PostgreSQL is unavailable. Wallet/Market health propagates the gate, and the public API returns HTTP 503 with `status=critical`.
|
||||
- Availability transition/recovery logs are structured JSON on stderr for the existing OTel collector. Outages use `CRITICAL`; recovery uses `INFO`.
|
||||
- Added GL to the development Procfile and explicit GL/availability/Kuknos settings to dev, stage, and main service configs.
|
||||
|
||||
Verification:
|
||||
|
||||
- Wallet: `go test ./...` passes.
|
||||
- GL: `go test ./...` passes (loopback test required the unrestricted runner).
|
||||
- API health tests pass in an isolated verification copy populated with compatible generated stubs. The checkout itself still requires its normal `buf generate` build step because `domain/stub/go` is not committed.
|
||||
|
||||
Deployment prerequisite: the compose files still need the actual GL image/service definition and database secret. The config intentionally points to `gl:8600`; without that service, health is critical and mutations remain halted.
|
||||
|
||||
Remaining architectural limit: health preflight closes the known outage path but cannot make a GL write and Kuknos submission atomic. GL-first acknowledged reservation/command processing plus reconciliation is still required for a strict cross-system guarantee.
|
||||
@@ -0,0 +1,24 @@
|
||||
# Darano assessment
|
||||
|
||||
Darano is a multi-service tokenization and trading platform centered on real-estate assets, with Mellat integration for fiat payments and Kuknos/Stellar for settlement. The recovered work adds a strong GL mirror and durable event infrastructure, but the requested target is not complete.
|
||||
|
||||
## Verdict
|
||||
|
||||
- Business domains are identifiable and documented in `02-business-domains.md`.
|
||||
- A project index and mind map are complete.
|
||||
- GL's feature branch is checked out, append-only, and its full tests pass. It is now started by the development Procfile and configured as `gl:8600`, but compose still needs a concrete GL service/image and database secret.
|
||||
- GL is the primary append-only financial truth; Kuknos is secondary settlement/verification truth. The new shared gate enforces both in normal mode, always halts on GL failure, and permits only an explicit startup-time `kuknos-enabled=false` mode. It never switches automatically.
|
||||
- User transactions are not uniformly event driven. The one-event-per-transaction design can publish a `CREATED` request too early and never re-enqueue it after confirmation; only four types have executable consumers.
|
||||
- Wallet and GL full suites pass. Tests now cover fail-closed RPC admission and paused event claims, but not complete cross-system user lifecycles or the health-check/commit race.
|
||||
|
||||
## Recommended next slice
|
||||
|
||||
1. Fix the command/event lifecycle and add end-to-end tests for internal transfer first.
|
||||
2. Replace monetary `float64` at service/persistence boundaries with fixed-point values.
|
||||
3. Add the concrete GL compose deployment/database secret, then implement reconciliation.
|
||||
4. Replace health-preflight-only coordination with GL-first acknowledged reservations/commands so GL and Kuknos cannot diverge across the check/submit race.
|
||||
5. Move AdminPanel mutations behind internal service APIs.
|
||||
|
||||
## Staging limitation
|
||||
|
||||
Direct interactive access to `https://stage.darano.ir` was unavailable. The supplied staging screenshots confirm wallet totals/locks, market and ICO purchase screens, legal agreement acceptance, transaction history, verified Sheba accounts, IRT withdrawal, and referrals; these flows are captured in `04-product-flows.md`.
|
||||
@@ -0,0 +1,47 @@
|
||||
# Darano mind map
|
||||
|
||||
```text
|
||||
Darano tokenization platform
|
||||
├── Customers and assets
|
||||
│ ├── Mellat Bank: primary customer and IPG rail
|
||||
│ ├── Real estate: principal real-world asset
|
||||
│ └── Token publisher: authorized ICO inventory owner
|
||||
├── Customer product
|
||||
│ ├── Login, identity, TFA, bank information
|
||||
│ ├── Projects and token discovery
|
||||
│ ├── Wallets, balances, trustlines
|
||||
│ ├── Buy, deposit, transfer, withdraw, redeem
|
||||
│ ├── Marketplace orders and history
|
||||
│ └── BNPL and referral commissions
|
||||
├── Financial orchestration
|
||||
│ ├── API gateway -> gRPC services
|
||||
│ ├── Wallet/Market -> validation and settlement
|
||||
│ ├── PostgreSQL -> operational state
|
||||
│ ├── Redis -> locks/cache
|
||||
│ └── RabbitMQ/Watermill -> transaction commands/events
|
||||
├── Sources of truth
|
||||
│ ├── GL -> primary append-only financial truth
|
||||
│ ├── Immutable double-entry journals
|
||||
│ ├── Transaction lifecycle events
|
||||
│ ├── Available/frozen/clearing/treasury accounts
|
||||
│ ├── Balance and journal explorer
|
||||
│ ├── Mirror transport: implemented foundation
|
||||
│ ├── Mandatory availability gate: missing
|
||||
│ ├── Critical health plus OTel incident reporting: missing
|
||||
│ └── Reconciliation: missing
|
||||
│ └── Kuknos (Stellar compatible) -> secondary settlement truth
|
||||
│ ├── Required together with GL in normal mode
|
||||
│ └── Manual operator disable mode: missing
|
||||
├── Operations
|
||||
│ ├── Django AdminPanel
|
||||
│ ├── Direct DB writes: current invariant bypass
|
||||
│ ├── DevOps/Traefik/Compose
|
||||
│ └── Monitoring and alerting
|
||||
└── Main work remaining
|
||||
├── Correct event command lifecycle
|
||||
├── Fixed-point money end to end
|
||||
├── GL fail-closed gate, startup/deployment, and reconciliation
|
||||
├── Trustline and reserved-balance GL model
|
||||
├── Critical health and OpenTelemetry incident reporting
|
||||
└── End-to-end domain/outage tests
|
||||
```
|
||||
Reference in New Issue
Block a user