6.8 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Repository Structure
This is a multi-service monorepo for the Darano financial/crypto platform. Each subdirectory is its own independent git repository:
| Directory | Language | Role |
|---|---|---|
api/ |
Go | HTTP REST gateway (Gin) — the only public-facing service |
auth/ |
Go | gRPC authorization service — OTP, JWT, permissions, identity |
wallet/ |
Go | gRPC wallet service — assets, transactions, Stellar blockchain, market |
ui/ |
TypeScript/Next.js | Customer-facing frontend |
AdminPanel/ |
Python/Django | Internal admin panel for manual ops |
proto/ |
Protobuf | Central schema definitions shared by all services |
DevOps/ |
Docker Compose | Infrastructure configs (Postgres, Redis, RabbitMQ, MinIO, Traefik) |
docs/ |
MkDocs | Documentation site |
Service Communication Architecture
The api gateway is the only HTTP-facing service. It receives REST requests and fans them out to backend gRPC services. All inter-service communication is gRPC using protobuf types defined in proto/.
Browser/Client → api (REST/HTTP) → auth, wallet, market (gRPC)
AdminPanel ──────────────────────→ Postgres directly (bypasses api)
The api/service/main.go defines DaranoService — a single interface that composes all upstream gRPC client interfaces (AuthorizationServiceClient, WalletServiceClient, MarketplaceSrvClient, AlertSrvClient, InternalAuthorizationServiceClient). Each backend service gets one persistent gRPC connection that auto-reconnects after a 2-minute timeout.
The wallet binary is multi-tenant: it serves wallet, market, alert, internal_wallet, and stream sub-services from one binary, selected via CLI subcommand.
Protobuf Code Generation
All services depend on generated code. Always run make build-proto before building any service. Proto definitions live in proto/, but each service has its own buf.gen.yaml that controls code generation into domain/stub/go/.
After generation, the Go makefiles strip omitempty from all JSON tags in .pb.go files — this is intentional and required for correct JSON serialization behavior.
For the UI, TypeScript types are generated from the same protos into src/types/stub/.
Commands
Go services (api/, 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/)
The wallet binary hosts multiple sub-services. During development, run each separately:
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 ...
make run-alert # ./build/main serve alert -c ./alert.cfg.toml
make grpc-ui-wallet # open grpcui on port 7210 (localhost:8200)
make grpc-ui-market # open grpcui on port 7300 (localhost:8300)
AdminPanel (AdminPanel/)
Uses uv for dependency management (pyproject.toml with uv backend):
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
UI (ui/)
yarn build-proto # generate TS types from protos (required first)
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)
Go Service Layer Pattern
auth and wallet both follow the same layered architecture:
config/— TOML config parsed viafig. Global singletonconfig.Cfg. All services started with--conf ./cfg.toml.domain/stub/go/— Generated protobuf Go code. Never edit manually.cmd/— Cobra CLI entry points. Cobra subcommands map to different serve modes.repository/— Data access.repository.System(auth) /repository.Repository(wallet) aggregatesIPostgres,IRedis,IService, andIQueue(wallet only) interfaces.usecase/(auth) /core/(wallet) — Business logic. Implements the gRPC server interfaces defined in proto.util/— Shared helpers; no business logic.
In auth, the usecase.UseCase interface directly embeds the generated gRPC server interfaces (authv1.AuthorizationServiceServer, authv1.InternalAuthorizationServiceServer).
API Gateway Routing Pattern
api/handler/routing.go organizes all routes into three groups:
/v1/public/— no auth required/v1/client/— requiresAuthorizationMiddleware(JWT validation via auth gRPC service)/v1/admin/— requiresAuthorizationMiddleware(currently mostly placeholder)
Handler files in api/handler/ map 1:1 to domains (wallet.go, market.go, authorization.go, etc.). All handlers call into the DaranoService interface and use MarshalResponse from response.go for consistent output.
UI Architecture
- Next.js App Router under
src/app/. Auth-protected routes: everything under/dashboard/(enforced bysrc/middleware.tsvia next-auth). src/services/— plain functions wrapping axios calls to the api gateway, typed with generated protobuf types.src/stores/— Zustand stores for global client state.src/hooks/— TanStack Query hooks built on top of the service functions.- Component library: HeroUI. Styling: Tailwind CSS with RTL support (Persian/Farsi UI).
- Formik + Yup for forms; react-hook-form used in some newer components.
Infrastructure
Dev infrastructure via DevOps/dev/infra-compose.yml: PostgreSQL 16, Redis, RabbitMQ, MinIO. All services connect to shared infra; each Go service has its own DB name.
All Go services instrument with Elastic APM (go.elastic.co/apm) and expose Prometheus metrics. Traefik handles TLS and routing in production.
Configuration
All Go services use TOML config files loaded by fig. The Peer struct in each service's config.go lists upstream gRPC addresses. Field names in Peer must exactly match the ServicesEnum string values used for reflection-based URL lookup.
The fig library reads struct tags (fig:"field-name") — use those when adding config fields, not environment variables.