Project Overview
Atlas Mall brings a real retail catalog into a cohesive digital experience. I built the storefront and the systems that support it: product discovery, detailed product pages, customer accounts, checkout, and an administration workspace. The design starts with Persian reading patterns, clear pricing, and a distinctive emerald identity. Underneath, Next.js, PostgreSQL, and Redis coordinate the work shoppers rarely see: reserving inventory, verifying payments, reconciling carts, and keeping published content current. The guiding question was simple: how do you make a complex shopping platform feel considered, clear, and easy to use?
Visual Showcase
01 / A recognizable first impression. The circuit monogram, emerald palette, and confident Persian typography establish the brand before the first product grid. Light and dark themes share the same hierarchy. Shopping entry points and reassurance stay close to the introduction, giving the visual identity a practical purpose.
02 / Make a large catalog approachable. Search, categories, brands, rating filters, and availability controls give shoppers several ways to narrow their choices. Product cards keep photography, names, discounts, and prices in a consistent rhythm. Filtering and pagination run at the database layer, rather than downloading the entire catalog into the browser.
05 / Recompose for the phone. The storefront, catalog, and product page each adapt to a narrow screen. Mobile discovery uses compact controls, the catalog retains a readable product grid, and product imagery stays prominent. Persistent navigation on the storefront and catalog keeps the main shopping destinations within reach.
The Challenge: Make Complexity Feel Simple
The interface had to serve two very different needs. Shoppers want to browse, compare, and buy without thinking about the software. Store operators need precise control over a changing catalog, campaigns, prices, inventory, and orders. A convincing storefront required both sides to work as one product.
- Build for Persian from the start. Right-to-left layouts, mixed Persian and Latin product names, long titles, and localized prices all influence spacing and hierarchy. Mirroring an English interface would leave those details unresolved.
- Balance atmosphere with utility. The brand needed room for expressive imagery and editorial storytelling, while search, product information, and purchase actions remained easy to find.
- Keep money and stock consistent. Checkout touches inventory, discounts, shipping, wallets, and external payment providers. Retries, simultaneous purchases, and delayed bank callbacks make this a state-management problem as much as a UI problem.
- Make publishing trustworthy. Cached storefront content must follow catalog and campaign changes. An administrator saving a change should not have to understand cache internals to see it reflected in the store.
- Give AI a bounded role. Shopping advice needs actual catalog facts. Administrative writing assistance needs a review step and a clear separation from automatic publishing.
The Approach: Craft Every Layer
I treated the visual language, shopping journey, and transaction model as parts of the same experience. The interface earns trust through clarity; the backend has to preserve that trust when something goes wrong.
A Persian design system with a clear visual rhythm
Atlas Mall's identity combines an emerald circuit monogram, quiet neutral surfaces, and Dana typography. DanaFaNum gives prices and counters consistent Persian numerals. Semantic color tokens support both light and dark themes, keeping brand, sale, stock, and focus states recognizable across the interface.
- RTL layouts and Persian interface labels are built into the product rather than added as a translation layer.
- Product photography leads; type, spacing, and restrained borders organize the supporting information.
- Keyboard focus, a skip-to-content link, labeled image controls, and carousel pause controls support accessible navigation.
Discovery that connects browsing to a confident choice
The catalog service handles search, filtering, sorting, and pagination in PostgreSQL. Shared taxonomy feeds categories and brands; curated collections offer a more editorial route into the same inventory. Product pages bring configuration, imagery, specifications, and comparison together before checkout.
- Server-rendered content and interactive client components divide the work between initial delivery and in-browser interaction.
- Zustand stores coordinate cart, wishlist, and comparison state with hydration guards.
- Optimistic cart changes are synchronized with the server; reconciled items replace local assumptions.
Checkout built around explicit state transitions
Order creation validates ownership and product configuration, calculates pricing on the server, and reserves stock inside a database transaction. Conditional updates guard inventory and order transitions. The payment layer exposes a shared interface across 13 Iranian provider adapters; only configured, enabled providers are offered at checkout.
- User-scoped idempotency handling protects order submission against retries.
- Gateway callbacks are checked against the order's selected provider and issued payment token.
- Ambiguous verification responses leave the order pending for reconciliation rather than immediately releasing its stock.
- Cancellation and expiry restore reservations; paid-order refunds use an append-only wallet ledger with a unique per-order refund constraint.
- Amounts remain in tomans internally and convert to integer rials at the payment-provider boundary.
Content operations that reach the storefront
Catalog, collection, banner, and campaign administration share an explicit cache-invalidation contract. After a mutation commits, the relevant tag versions are advanced before the service returns success. An older request completing later can populate its old cache key, but subsequent requests use the new version.
- Tag-versioned Redis caching combines stale-while-revalidate delivery with single-flight rebuilds.
- Product and taxonomy changes invalidate dependent views together, including category and brand counts.
- When Redis reads fail, content loaders fall back to the database.
AI assistance with distinct responsibilities
The shopping advisor uses catalog tools to retrieve products and their details, with a catalog-search fallback when no provider key is configured. The administrative content assistant follows a separate path: supplied facts become editable drafts and review notes, then an operator decides what to apply and save.
- Customer and administrator assistance have independent enablement controls.
- Administrative generation validates a structured response and the destination field's length limit.
- The writing assistant has no direct publishing action; applying a draft updates the editor, and saving remains a separate operation.
Results & Impact
- Product DeliveryLive
A publicly accessible storefront at atlasmall.net, backed by a real product catalog and connected administration workflows.
- Payment Architecture13 adapters
A shared payment contract integrates Iranian providers. Availability is controlled per provider; live processing depends on each provider's configuration and credentials.
- Connected OperationsEnd to end
Catalog discovery, cart reconciliation, transactional ordering, payment verification, and content administration share a coherent application architecture.
The Technology Behind the Experience
The stack supports a rich shopping interface without separating the storefront from its operational model. Next.js and React deliver the application; TypeScript carries contracts between the UI and services; PostgreSQL holds authoritative commerce data; Redis supports caching and coordination.
- Next.js App Router + React: Server Components for content delivery, interactive components for search, product configuration, and shopping state.
- TypeScript + Zod: Typed application boundaries and validated request input.
- Prisma + PostgreSQL: Relational catalog and order models, transactions, and guarded state changes.
- Redis: Tagged content caches, session revocation, rate budgets, and order retry coordination.
- Tailwind + semantic tokens: Shared visual foundations for RTL layouts, responsive surfaces, and two themes.
- Docker + observability: Containerized infrastructure, structured logging, Sentry integration, and optional OpenTelemetry tracing.
Decisions That Keep the Product Coherent
The most useful architecture decisions protect a specific user experience: accurate stock, understandable payment states, fresh content, and a UI that responds immediately.
A layered application with shared domain services
Routes authenticate and validate; services own business rules; repositories handle data access for core commerce domains. This keeps the same ordering rules available to customer and administrative flows, while making those rules independently testable.
Database truth with optimistic interaction
Local cart changes make the interface feel responsive, but the server reconciles them. Prices, stock, coupons, and ownership are validated again when creating an order. Fast feedback and authoritative validation serve different purposes, so both are necessary.
Treat a payment timeout as uncertainty
An unreachable provider does not establish that a payment failed. Leaving an inconclusive verification pending preserves the order for a later callback or reconciliation. Gateway-bound orders receive a longer expiry window than ordinary abandoned checkouts.
Separate AI generation from publication
A draft can improve editorial speed without becoming a source of unreviewed product claims. The administrative assistant works from supplied facts, returns review notes, and leaves applying and saving to the operator.
Built for Everyday Operations
Running a store means preparing for external-service failures, content updates, abandoned orders, and changing account permissions. Those cases shape the platform alongside its visible features.
- Containerized deployment: Docker configuration groups the application with PostgreSQL, Redis, and an NGINX reverse proxy.
- Verified account boundaries: Protected requests check signed sessions, revocation, active user state, and role authorization on the server.
- Reservation recovery: Expiry routines release stale pending orders and limited-drop holds through guarded transactional updates.
- Failure visibility: Structured logs and tracing hooks capture operational context; graceful shutdown drains infrastructure connections.
- Focused regression coverage: Unit, integration, and browser test sources cover commerce and administration flows. Provider adapters use mocked protocol tests; real bank processing requires separate environment-specific verification.
Good Commerce Is a Connected Experience
Atlas Mall brings together the two kinds of work I care about: shaping an interface people enjoy using and engineering the systems that make it dependable. The most satisfying details are the connections between them. A clear price depends on server-side pricing. A confident purchase depends on correct stock reservations. A fresh campaign depends on reliable publishing and invalidation. The next step is to learn from real shopping behavior and refine discovery and checkout with measured evidence. The delivered platform is live; conversion lifts, revenue impact, and reliability percentages need analytics before they can become part of this story.
Key Takeaways
- Start with the reader. Persian typography, RTL structure, and currency formatting belong in the foundation of the design.
- Design the whole journey. Editorial browsing, product evaluation, and checkout should feel like parts of one product.
- Model the difficult states. Retries, delayed callbacks, and abandoned reservations deserve explicit behavior.
- Keep trust measurable. Show what has been built and verified; let real usage data establish business impact.


