Skip to content

docs: Initial approach and architecture for wallet transfer service - #105

Open
anilkumar2809 wants to merge 2 commits into
Robustrade:mainfrom
anilkumar2809:solution/anilkumar-yalla
Open

docs: Initial approach and architecture for wallet transfer service#105
anilkumar2809 wants to merge 2 commits into
Robustrade:mainfrom
anilkumar2809:solution/anilkumar-yalla

Conversation

@anilkumar2809

Copy link
Copy Markdown

Summary

Describe your solution briefly.

1. Core Understanding

The goal is to build a highly reliable, concurrent wallet-to-wallet transfer Service.
The primary engineering challenges are guaranteeing exactly-once processing (idempotency), strictly maintaining a balanced double-entry ledger, and preventing race conditions/deadlocks during concurrent requests.

2. Proposed Architecture & Stack

  • Stack: Go, Gin (for HTTP routing), and PostgreSQL.
  • Architecture: Clean, layered separation (Handler $\rightarrow$ Service $\rightarrow$ Repository $\rightarrow$ Domain).
  • To maintain a clean separation of concerns, the service will be structured using a clean, layered architecture: Handler Layer (HTTP routing/validation) $\rightarrow$ Service Layer (orchestration/business rules) $\rightarrow$ Repository Layer (SQL queries/database transactions) $\rightarrow$ Domain Models (core entities/state transitions).

3. Database Schema (PostgreSQL)

I will use 4 primary tables.

  • idempotency_records: idempotency_key(PRIMARY KEY), request_hash, response_status, response_body, created_at(TIMESTAMP with TIME ZONE DEFAULT CURRENT_TIMESTAMP).
  • wallets: id, balance (with a CHECK balance >= 0 constraint).
  • transfers: id, idempotency_key (UNIQUE index), from_wallet_id, to_wallet_id, amount, status.
  • ledger_entries: id, transfer_id, wallet_id, type (DEBIT/CREDIT), amount.

(Note: To favor simplicity and prevent orphaned states in the event of an application crash, I am executing all the operations on the tables and handling everything within a single transaction).

4. Concurrency & Idempotency Strategy

I will rely on PostgreSQL's native ACID properties to handle distributed system edge cases:

  • Idempotency: A UNIQUE constraint on idempotency_records.idempotency_key. If a concurrent retry hits the DB, the uncommitted lock will briefly block it, then safely reject it once the first transaction completes, allowing the API to return the processed response/status.
  • Concurrency (Race Conditions): The entire transfer lifecycle will be wrapped in a single database transaction. I will use pessimistic locking (SELECT ... FOR UPDATE) on the wallet rows to ensure sequential balance deductions.
  • Deadlock Prevention: To prevent A $\rightarrow$ B and B $\rightarrow$ A deadlocks, the application will consistently sort the wallet UUIDs lexicographically(fromWalletId, then toWalletId) before acquiring the row locks.

5. Design Decisions & Trade-offs

Chosen Approach: Single Atomic Transaction
  • Pros: Simplicity. Zero possibility of orphaned states (such as writing an idempotency key as PENDING but crashing before money moves, locking the user out indefinitely). Relies directly on the maturity of PostgreSQL ACID mechanics.

  • Cons : Concurrent retries will briefly hang/block at the database level while waiting for the original transaction to commit, rather than immediately returning a 409 Conflict. Given a targeted REST API response time of $<50\text{ms}$, this brief block is a preferred trade-off over implementing asynchronous sweepers and cleanup crons.

6. Scaling(Not Going to implement but design constraints)

  • Consider implementing patroni cluster for better node management
  • consider Implementing DB wrapper such that underlying application interacts with the DB wrapper and need not be aware of the underlying DB, such that we can swap out for mySQL, Oracle DB if required later.
  • Consider implementing the logic to maintain the connection pool.
  • consider implementing additional services/crontabs and additiona of Queues to retry/clearn any dangling requests.

AI disclosure

Detail how you used AI to help with your submission (including the tools you used, how
you used them and what your prompts were).
Include these points in detail

  1. What tool you used (Cursor, Claude Code, Antigratvity etc.) Antigravity for most of the task, Gemini for some clarifications related to postgres details like types of locks.
  2. How you generally use the tool for your work. --> I use Gemini Chat generally to get to know about certain topics, summary and use Antigravity for coding related tasks. I would try to understand the requirements first and note down the system design, then will invoke antigravity to correct me, including drawbacks and better approaches, adjustment of code comments.
  3. A transcript of your entire session with your AI tool of choice. You can add this to the repo or email it to us with your submission. If for some reason, this is not possible, give us all the prompts that you used with the AI.
    I have included it a sperate file as AI_USAGE.md

Schema Design

Describe the tables, constraints, and indexes you introduced.

Idempotency Strategy

Explain how duplicate requests are handled safely.

Concurrency Strategy

Explain how you prevent race conditions and double spending.

How to Run

How to Test

Tradeoffs / Assumptions

Checklist

  • Tests pass
  • Lint passes
  • Format check passes
  • README or notes updated
  • PR description explains schema, idempotency, and concurrency

Copilot AI review requested due to automatic review settings July 2, 2026 15:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds initial design and AI-usage documentation for the wallet transfer assignment, focusing on proposed architecture, database schema, idempotency, and concurrency approach.

Changes:

  • Introduces DESIGN.md outlining the intended layered architecture, schema, and locking/idempotency strategy.
  • Adds AI_USAGE.md documenting how AI tools were used during the design phase.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
DESIGN.md Documents proposed architecture, schema, and concurrency/idempotency approach for the wallet transfer service.
AI_USAGE.md Records AI tooling usage and design discussion transcript.

Comment thread DESIGN.md

I will rely on PostgreSQL's native ACID properties to handle distributed system edge cases:

* **Idempotency:** A `UNIQUE` constraint on `idempotency_records.idempotency_key`. If a concurrent retry hits the DB, the uncommitted lock will briefly block it, then safely reject it once the first transaction completes, allowing the API to return the processed response/status.
Comment thread DESIGN.md

* **Idempotency:** A `UNIQUE` constraint on `idempotency_records.idempotency_key`. If a concurrent retry hits the DB, the uncommitted lock will briefly block it, then safely reject it once the first transaction completes, allowing the API to return the processed response/status.
* **Concurrency (Race Conditions):** The entire transfer lifecycle will be wrapped in a single database transaction. I will use pessimistic locking (`SELECT ... FOR UPDATE`) on the wallet rows to ensure sequential balance deductions.
* **Deadlock Prevention:** To prevent A $\rightarrow$ B and B $\rightarrow$ A deadlocks, the application will consistently sort the wallet UUIDs lexicographically(fromWalletId, then toWalletId) before acquiring the row locks.
Comment thread DESIGN.md
Comment on lines +42 to +46
#### 6. Scaling(Not Going to implement but design constraints)
* Consider implementing patroni cluster for better node management
* consider Implementing DB wrapper such that underlying application interacts with the DB wrapper and need not be aware of the underlying DB, such that we can swap out for mySQL, Oracle DB if required later.
* Consider implementing the logic to maintain the connection pool.
* consider implementing additional services/crontabs and additiona of Queues to retry/clearn any dangling requests. No newline at end of file
Comment thread AI_USAGE.md
Comment on lines +2 to +3
Additional Prompts used on Gemini to get clarity
PostgresSQL locking mechanisms including pessismistic locking and also different types of lock mechanisms.
Comment thread AI_USAGE.md

How would you briefly address the "merchant contention" issue in the PR notes without actually over-engineering the code to solve it right now?

*Viewed [ASSIGNMENT.md](file:///Users/anilkumaryalla/Desktop/git_repo/wallet-transfer-assignment/ASSIGNMENT.md) *
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants