For CompaniesSign InSign Up

Build real things.
Prove you can engineer.

Companies post real engineering problems. You solve them. We evaluate your code, your commits, and your design decisions. Top profiles get found by hiring teams.

Start your first build

Free to start. No credit card.

Portfolio projects

You built real things. The problem is, nobody ever looked at the engineering behind them — so it all blends into the same pile.

Certificates & courses

A stack of certificates says you finished the course. It doesn't say much about the choices you'd make when the problem isn't laid out for you.

Campus placements

A resume gets about seven seconds of attention. That's not enough time for anyone to see what you're actually good at.

The problem isn't your skill. It's that nothing you're doing right now actually proves it.

How it works

Here's what actually works. Three steps. No resumes. No algorithm quizzes.

Step 01

Pick a build

Browse open builds posted by real companies. Each one is a real engineering problem — not a DSA puzzle or a tutorial project.

Step 02

Push your solution

Work in your own IDE. When you’re done, submit your GitHub repo. That’s the entire submission process.

Step 03

Get your review

XVal reviews your code and the decisions behind it. You get written feedback on what worked, what to sharpen, and which dimensions came through strongest.

This is what your review looks like

Every submission gets one. Real feedback on the decisions you made, the tradeoffs you weighed, and where to sharpen next.

Stealth Fintech Startup

Payment Reconciliation Service

Engineering Assessment

Effective AI user with genuine engineering ownership.

The git history shows someone thinking out loud: a first pass at the adapters, a refactor when the retry duplication became obvious, then a dedicated commit to carve out the error hierarchy. AI clearly helped draft code, but the shape of the solution — adapter boundaries, error types, batch handling — came from the candidate.

What stood out

  • Chose the adapter pattern before any provider-specific code was written
  • Introduced a typed error hierarchy instead of leaning on generic Error
  • Caught a subtle duplicate-transaction edge case through unique indexes

Where to grow

  • Retry logic was duplicated across three adapters before being noticed
  • No integration tests for partial batch failures — the most likely production failure mode

You kept the reconciliation logic separate from each payment provider, which is the right call. If you ever need to swap out Stripe for a new provider, you only change one file. One thing to work on: you wrote the retry logic three times, once per provider. Pull that into a shared function so you only have to maintain it in one place.

Build & Test

Partial
Install DependenciesPassed8.2s
Build / CompilePassed4.1s
Run TestsFailed6.1s

6 of 8 tests passed. 2 failures in batch processing suite.

Code Quality

Readability
good
  • Variable names in BatchProcessor.ts use abbreviations (txn, rcn) that reduce scannability
  • +Consistent file structure across all service modules with clear separation of imports, types, and logic
  • +TypeScript interfaces defined close to usage rather than in a central types file — good colocation
Error Handling
good
  • Bare catch blocks in BatchProcessor.ts:92 swallow errors silently during batch retries
  • +Typed error hierarchy (ReconciliationError, GatewayTimeoutError) enables precise recovery per failure mode
  • +Gateway adapters propagate error context up the call chain cleanly
Testing
fair
  • No integration tests for concurrent batch processing — tests/ covers individual adapter units only
  • Test fixtures hardcode gateway responses instead of using factory patterns
  • +Unit tests cover core reconciliation logic with good edge case coverage for individual adapters

Design Quality

Architecture
good
  • BatchProcessor imports concrete adapter classes — no dependency injection
  • +Clean bounded contexts between reconciliation, gateway, and discrepancy domains
  • +Adapter pattern in src/types/GatewayAdapter.ts enables zero-downtime provider rotation
Abstractions
fair
  • Retry logic duplicated across StripeAdapter.ts:61, PayPalAdapter.ts:44, SquareAdapter.ts:52
  • Configuration values scattered across files instead of centralized env config
  • +Gateway adapter interface is well-abstracted with clear contract boundaries
Data & API Design
excellent
  • +Compound unique indexes in src/models/Transaction.ts prevent duplicate reconciliation entries across restarts
  • +API routes follow RESTful conventions with proper HTTP semantics
  • +Database schema normalizes gateway-specific fields without over-engineering the shared model
Complexity Balance
good
  • DiscrepancyDetector could be simplified by using event emitter pattern instead of manual callback chain
  • +Solution complexity matches problem scope — no unnecessary abstraction layers

Review Summary

You kept the reconciliation logic separate from each payment provider, which is the right call. If you ever need to swap out Stripe for a new provider, you only change one file. One thing to work on: you wrote the retry logic three times, once per provider. Pull that into a shared function so you only have to maintain it in one place.

Strengths

  • Each payment provider has its own adapter file with a shared interface. This means adding a new provider is one new file, not a rewrite.
  • Your transactions table uses unique indexes to prevent duplicates. If the service crashes mid-reconciliation and restarts, it picks up without creating double entries.
  • You created specific error types like ReconciliationError and GatewayTimeoutError. This makes it easy to handle each failure case differently instead of catching everything with a generic handler.

Areas for Improvement

  • You wrote retry logic three times (StripeAdapter.ts:61, PayPalAdapter.ts:44, SquareAdapter.ts:52). Pull it into one shared function so changes apply everywhere.
  • Your tests cover individual adapters but not what happens when a batch fails halfway through. Add an integration test that simulates one provider going down mid-batch.
  • Timeout values are hardcoded in PayPalAdapter.ts:47 and StripeAdapter.ts:83. Move these to environment config so you can tune them without redeploying.

Key Issues

majorRetry logic written separately in each of the 3 payment adapters with different backoff strategies

src/adapters/StripeAdapter.ts:61, PayPalAdapter.ts:44, SquareAdapter.ts:52

Create a shared withRetry() function with configurable backoff. All three adapters should use it.

In production payment systems, retry logic is shared infrastructure. When it is duplicated, the copies drift apart over time and bugs only get fixed in one place.

majorNo tests for what happens when a payment provider fails during a batch

tests/adapters/

Write a test where one provider goes down mid-batch. Make sure the transactions that already went through are safe.

Partial batch failures are the most common failure mode in payment systems. Testing for them is not optional.

minorBatchProcessor directly imports each adapter class instead of receiving them as parameters

src/handlers/BatchProcessor.ts:12–14

Pass adapters into the constructor. This makes testing easier and lets you add new providers without changing BatchProcessor.

This is called dependency injection. It is how production systems stay flexible when new integrations are added.

Multi-gateway reconciliation enginecore

src/services/ReconciliationEngine.ts, src/adapters/StripeAdapter.ts, PayPalAdapter.ts, SquareAdapter.ts

Complete
Real-time discrepancy detectioncore

src/services/DiscrepancyDetector.ts — event-driven flagging within reconciliation loop

Complete
Consistent error recovery across service boundariescore

Typed errors in src/errors/ but bare catch blocks in src/handlers/BatchProcessor.ts:92

Partial
Batch processing with retry semanticssecondary

src/handlers/BatchProcessor.ts — batching works but retry strategy inconsistent across adapters

Complete
API documentation & endpoint specpolish

No OpenAPI spec found — README.md covers features only

Missing
src/config/defaults.ts:12Default timeout value appears hardcoded — consider environment variable

Code Files

18

Avg Lines/File

94.0

Max File Lines

312

Concentration

14%

Folder Depth

4

Comment Ratio

6%

Used AI tools? Good. We evaluate your engineering decisions, not who typed the code.

Four builds. Four honest reviews.

Feedback that shows where you're strong, where you're developing, and what to work on next.

BuildFocusReadabilityError HandlingArchitecture
Build 1First real backendfairpoorfair
Build 2Learned to catch failuresgoodfairfair
Build 3Started thinking in layersgoodgoodgood
Build 4Design decisions, not just codeexcellentgoodexcellent

Every review shows exactly where you stand and what to work on next.

Open builds

Real engineering problems from real companies. Pick one and start building.

Stealth Series A Fintech

Payment Reconciliation Service

Design a service that reconciles payment records across multiple gateway providers and flags discrepancies in real time.

Node.jsPostgreSQLEvent-Driven

Stealth B2B SaaS Startup

Multi-Tenant Notification Engine

Build a notification system that supports email, SMS, and in-app channels with per-tenant rate limiting and delivery tracking.

TypeScriptRedisREST API

Stealth D2C Platform

Route Optimization API

Create an API that calculates optimal delivery routes given a set of waypoints, time windows, and vehicle constraints.

PythonFastAPIAlgorithms

Your verified build profile

Every build you complete adds to a profile that companies actually search. Not a resume. Not a certificate. Proof.

ReadabilityError HandlingTestingArchitectureAbstractionsData & APIDesignComplexityBalance

Based on 5 completed builds

Payment Reconciliation Service

Stealth Fintech Startup

Clean adapter pattern, typed error hierarchy

Multi-Tenant Notification Engine

Series A SaaS Company

Thoughtful tenant isolation, strong observability

Route Optimization API

B2B Logistics Platform

Solid core logic, lighter on edge-case handling

Real-Time Chat Backend

EdTech Scale-Up

Good concurrency model, clean backpressure handling

Inventory Sync Pipeline

D2C E-Commerce Startup

Pragmatic design, well-tested happy path

Share it. Or let companies find you.

Companies post builds to find engineers to hire. When you rank in their challenge, you're on their shortlist. A company searching for “Node.js engineers with strong architecture” will see your profile. You don't apply. They find you.

Hiring engineers?

Post a real engineering problem. Receive ranked candidates with full evaluation reports and GitHub proof.

Post a challenge →