7.9 KiB
MercadoDeVida vNext — Caveman Architecture
SIMPLE CODE. CLEAR MODULES. SMALL CHANGES. NO MAGIC.
0. CORE PHILOSOPHY
Build boring software. Boring = good.
Prefer: simple code, explicit dependencies, small modules, clear APIs, strong typing, predictable behavior, easy testing, easy replacement, easy debugging.
Avoid: clever abstractions, unnecessary microservices, circular dependencies, global state, giant service classes, framework magic.
The system must be easy for humans AND AI agents to understand.
1. ARCHITECTURE
Modular Monolith — each business domain is an isolated module.
src/
├── modules/
│ ├── auth/ # Identity module (sessions, login, register)
│ ├── users/ # User profiles
│ ├── catalog/ # Products, variants, attributes
│ ├── categories/ # Category taxonomy
│ ├── brands/ # Brand management
│ ├── pricing/ # Price calculation + VAT
│ ├── promotions/ # Discounts, promo codes
│ ├── inventory/ # Stock management
│ ├── cart/ # Shopping cart
│ ├── checkout/ # Checkout orchestrator
│ ├── orders/ # Order management
│ ├── payments/ # Payment provider interface
│ ├── shipping/ # Shipping zones and methods
│ ├── seo/ # SEO metadata
│ ├── cms/ # Content management
│ ├── reviews/ # Product reviews
│ ├── notifications/ # Email/push notifications
│ ├── cache/ # Caching layer
│ ├── security/ # Rate limiting, audit log, MFA
│ ├── observability/ # Traces, metrics
│ └── flags/ # Feature flags
├── shared/
├── infrastructure/
└── app/
Modules communicate through: (1) explicit public interfaces, (2) domain/application events, (3) typed contracts. Never access another module's internal implementation.
2. MODULE RULE
Every module owns its logic. Structure:
modules/<name>/
├── domain/ # Pure business rules. No DB, no HTTP, no framework.
├── application/ # Use cases: CreateProduct, ReserveStock, CreateOrder
├── infrastructure/ # PostgreSQL, Redis, Stripe, Email adapters
├── api/ # Thin HTTP controllers
├── tests/ # Unit + boundary tests
└── index.ts # Public API only
Controllers must be thin: request → validate → use case → response. NO business logic in controllers.
3. SDD IS MANDATORY
NO FEATURE STARTS WITH CODE. Every change starts with a specification.
Directory: specs/<feature>/
Each feature gets:
SPEC.md— Problem, Goal, User story, Functional requirements, Acceptance criteriaDESIGN.md— Affected modules, new interfaces, API changes, DB changes, eventsTASKS.md— Small atomic tasksTESKS.md— Required tests- Optional:
ADR.md,MIGRATION.md,ROLLBACK.md
4. TECH STACK
Frontend
- Next.js + React + TypeScript + Tailwind CSS
- Server Components where useful
- SSR/SSG for SEO-sensitive pages
- Client-side only where interaction requires it
Backend
- TypeScript + Node.js + Fastify
- Strict module boundaries
- PostgreSQL (primary database)
- Redis (cache, sessions, rate limiting — NOT source of truth)
Observability
- Structured logs, metrics, traces
- OpenTelemetry-compatible interfaces
- Per-module metrics
5. DATABASE RULES
Database belongs to modules. Logical ownership must remain clear.
Naming: <module>_<entity> — e.g., catalog_products, orders_orders, inventory_stock.
Never let random modules query arbitrary tables. Access data through module interfaces only.
6. CORE BUSINESS RULES
- Catalog ≠ Inventory: Catalog answers "what is this product?"; Inventory answers "can I sell it?"
- Cart ≠ Checkout: Cart stores items; Checkout validates, calculates, orchestrates
- Checkout is orchestrator: coordinates cart, pricing, inventory, shipping, orders, payments
- Orders are historical: snapshot product name, SKU, EAN, prices, taxes at creation time
- Payment provider behind interface: StripePaymentProvider, RedsysPaymentProvider — domain never imports Stripe SDK directly
- Backend calculates everything: never trust price, stock, discount, total from frontend
- Idempotency everywhere: checkout, webhooks, payment operations
7. SEO IS CORE BUSINESS LOGIC
Support: canonical URLs, structured data (Product, Breadcrumb, Organization schema), sitemap.xml, robots.txt, OpenGraph, metadata per page.
URLs: /productos/<slug>, /categoria/<slug>, /marca/<slug>.
8. CAVEMAN RULES
ONE MODULE = ONE JOB
ONE USE CASE = ONE PURPOSE
DATABASE = SOURCE OF TRUTH
REDIS = CACHE, NOT TRUTH
CONTROLLER = THIN
BUSINESS LOGIC = DOMAIN
EXTERNAL API = ADAPTER
NO CROSS-MODULE TABLE QUERIES
NO GLOBAL STATE
NO HIDDEN MAGIC
NO COPY-PASTE BUSINESS LOGIC
NO FEATURE WITHOUT SPEC
NO DATABASE CHANGE WITHOUT MIGRATION
NO CRITICAL LOGIC WITHOUT TEST
NO EXTERNAL EVENT WITHOUT IDEMPOTENCY
NO PAYMENT TRUST FROM FRONTEND
NO PRICE TRUST FROM FRONTEND
NO BIG REWRITE
SMALL CHANGE
TEST CHANGE
SHIP CHANGE
9. FRONTEND STRUCTURE (to be built)
frontend/
├── src/
│ ├── app/ # Next.js App Router pages
│ │ ├── (shop)/ # Shop routes (product, category, brand, search)
│ │ ├── (checkout)/ # Cart + checkout flow
│ │ ├── (account)/ # User account, orders
│ │ ├── (admin)/ # Admin panel (protected)
│ │ └── api/ # API routes
│ ├── components/ # Shared UI components
│ │ ├── ui/ # Base components (Button, Input, Card...)
│ │ ├── product/ # Product-specific components
│ │ ├── cart/ # Cart components
│ │ └── layout/ # Header, Footer, Nav
│ ├── modules/ # Module-specific frontend code (mirrors backend modules)
│ ├── lib/ # Utilities, API client, types
│ └── styles/
├── public/
└── tests/
├── unit/
├── integration/
└── e2e/
Pages to build (Frontend v1):
- Homepage — Hero, featured products, categories, brand highlights
- Category page — Product listing with filters, pagination, SEO metadata
- Product detail page — Images, description, nutrition, reviews, add to cart
- Brand page — Brand info + brand products
- Search results page — Search with filters
- Cart page — Cart items, totals, promo code
- Checkout — Address, shipping, payment, order summary
- Order confirmation — Order details, next steps
- User account — Profile, orders history, addresses
- Admin panel — Product CRUD, order management, CMS
10. FRONTEND-BACKEND COMMUNICATION
Frontend communicates with backend via:
- Server Components (SSR): Direct DB queries through Prisma/Postgres (same DB, no HTTP overhead)
- Server Actions: Form submissions, mutations (type-safe, no REST overhead)
- API Routes (minimal): External integrations, webhooks, special cases
Never call backend REST API from client components. Use Server Components and Server Actions.
11. TESTING PYRAMID
- Unit tests: Business rules in domain/application layers — many
- Integration tests: Repositories against real DB, API endpoints — some
- E2E tests: Critical flows — few
Critical E2E flows: register → login → search → view product → add to cart → checkout → payment → order confirmation
12. DEFINITION OF DONE
A feature is DONE when:
- SPEC.md complete with testable acceptance criteria
- DESIGN.md reviewed and approved
- Implementation complete (smallest possible change)
- Unit + integration tests passing
- Security reviewed
- Observability added (logs/metrics)
- Documentation updated
- Migration tested
- Rollback possible
- Acceptance criteria verified against spec