{"id":49945758,"url":"https://github.com/dan1d/clover_sandbox_simulator","last_synced_at":"2026-05-17T15:15:27.678Z","repository":{"id":335880221,"uuid":"1146902064","full_name":"dan1d/clover_sandbox_simulator","owner":"dan1d","description":"Ruby gem for simulating realistic restaurant POS operations in Clover sandbox environments. Generate orders, payments, and transaction data for testing Clover API integrations.","archived":false,"fork":false,"pushed_at":"2026-02-13T05:14:44.000Z","size":410,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-07T11:07:29.484Z","etag":null,"topics":["clover","clover-api","pos","restaurant","ruby","sandbox","testing"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dan1d.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-31T21:36:35.000Z","updated_at":"2026-02-13T05:14:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dan1d/clover_sandbox_simulator","commit_stats":null,"previous_names":["dan1d/clover_sandbox_simulator"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dan1d/clover_sandbox_simulator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dan1d%2Fclover_sandbox_simulator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dan1d%2Fclover_sandbox_simulator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dan1d%2Fclover_sandbox_simulator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dan1d%2Fclover_sandbox_simulator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dan1d","download_url":"https://codeload.github.com/dan1d/clover_sandbox_simulator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dan1d%2Fclover_sandbox_simulator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33143295,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T09:28:26.183Z","status":"ssl_error","status_checked_at":"2026-05-17T09:27:52.702Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clover","clover-api","pos","restaurant","ruby","sandbox","testing"],"created_at":"2026-05-17T15:15:26.379Z","updated_at":"2026-05-17T15:15:27.671Z","avatar_url":"https://github.com/dan1d.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Clover Sandbox Simulator\n\nA Ruby gem for simulating Point of Sale operations in Clover sandbox environments. Generates realistic orders, payments, and transaction data across **9 business types** for testing integrations with Clover's API.\n\n## Features\n\n- **9 Business Types**: Restaurant, Cafe/Bakery, Bar/Nightclub, Food Truck, Fine Dining, Pizzeria, Retail Clothing, Retail General, Salon/Spa — each with tailored categories and items\n- **168 Menu/Product Items**: Spread across 38 categories with realistic pricing\n- **Modifier Groups**: Temperature, add-ons, sides, dressings, drink sizes applied to menu items\n- **Multiple Payment Methods**: Credit/Debit cards via Ecommerce API, plus Cash, Check, Gift Card, and other tenders\n- **Split Payments**: Supports 1-4 tender splits per order, more common for larger parties\n- **Meal Period Simulation**: Orders distributed across breakfast, lunch, happy hour, dinner, and late night with realistic weights\n- **Order Types**: Dine-in, Takeout, and Delivery with configurable settings\n- **Service Charges**: Auto-gratuity for large parties (18% for 6+ guests)\n- **Dynamic Order Volume**: Different order counts for weekdays, Friday, Saturday, Sunday (40-120 orders/day)\n- **Tips \u0026 Taxes**: Variable tip rates by dining option (15-25% dine-in, 0-15% takeout, 10-20% delivery)\n- **Per-Item Tax Rates**: Different tax rates for food vs alcohol items\n- **Discounts**: 7 discount types including Happy Hour, promo codes, loyalty, combo, line-item, threshold, and legacy\n- **Employees \u0026 Customers**: Auto-generated with realistic names and contact info\n- **Shift Tracking**: Clock in/out for employees with duration tracking\n- **Cash Drawer Management**: Open/close drawer events with cash tracking\n- **Party Size Variation**: 1-6 guests affecting item counts and split payment probability\n- **Order Notes**: Random special instructions (allergies, modifications, VIP customers)\n- **PostgreSQL Audit Trail**: Track all simulated orders, payments, and API requests in a local database\n- **Daily Summaries**: Automated aggregation of revenue, tax, tips, and discounts by meal period and dining option\n- **Database Seeding**: Idempotent FactoryBot-based seeder for all 9 business types\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'clover_sandbox_simulator'\n```\n\nAnd then execute:\n\n```bash\nbundle install\n```\n\nOr install it yourself as:\n\n```bash\ngem install clover_sandbox_simulator\n```\n\n## Configuration\n\n### Multi-Merchant Setup (Recommended)\n\nCreate a `.env.json` file with the object format:\n\n```json\n{\n  \"DATABASE_URL\": \"postgres://localhost:5432/clover_simulator_development\",\n  \"merchants\": [\n    {\n      \"CLOVER_MERCHANT_ID\": \"YOUR_MERCHANT_ID\",\n      \"CLOVER_MERCHANT_NAME\": \"My Test Merchant\",\n      \"CLOVER_API_TOKEN\": \"static-api-token\",\n      \"CLOVER_ACCESS_TOKEN\": \"oauth-jwt-token\",\n      \"CLOVER_REFRESH_TOKEN\": \"clvroar-refresh-token\",\n      \"PUBLIC_TOKEN\": \"ecommerce-public-token\",\n      \"PRIVATE_TOKEN\": \"ecommerce-private-token\"\n    }\n  ]\n}\n```\n\nThe legacy array format is also supported for backwards compatibility:\n\n```json\n[\n  {\n    \"CLOVER_MERCHANT_ID\": \"YOUR_MERCHANT_ID\",\n    \"CLOVER_API_TOKEN\": \"your-token\"\n  }\n]\n```\n\n**Token Types:**\n- `CLOVER_API_TOKEN` - Static API token (never expires, preferred)\n- `CLOVER_ACCESS_TOKEN` - OAuth JWT token (expires, can be refreshed)\n- `PUBLIC_TOKEN` / `PRIVATE_TOKEN` - Required for credit card payments via Ecommerce API\n- `DATABASE_URL` - PostgreSQL connection string for audit trail persistence\n\n### Single Merchant Setup\n\nAlternatively, use a `.env` file:\n\n```env\nCLOVER_MERCHANT_ID=your_merchant_id\nCLOVER_API_TOKEN=your_api_token\nCLOVER_ENVIRONMENT=https://sandbox.dev.clover.com/\nPUBLIC_TOKEN=your_ecommerce_public_token\nPRIVATE_TOKEN=your_ecommerce_private_token\nLOG_LEVEL=INFO\nTAX_RATE=8.25\n```\n\n### Database Setup\n\nThe simulator uses PostgreSQL to persist audit data (simulated orders, payments, API requests, daily summaries). Set up the database with:\n\n```bash\n# Create, migrate, and seed the database\n./bin/simulate db reset\n\n# Or step by step:\n./bin/simulate db create\n./bin/simulate db migrate\n./bin/simulate db seed\n```\n\n## Usage\n\n### Quick Start\n\nRun a full simulation (setup + generate orders):\n\n```bash\n./bin/simulate full\n```\n\n### Commands\n\n```bash\n# Show version\n./bin/simulate version\n\n# List available merchants from .env.json\n./bin/simulate merchants\n\n# Set up restaurant entities (categories, items, discounts, etc.)\n./bin/simulate setup\n\n# Generate orders for today (random count based on day of week)\n./bin/simulate generate\n\n# Generate a specific number of orders\n./bin/simulate generate -n 25\n\n# Generate orders with refunds (5% default, customize with -r)\n./bin/simulate generate -n 25 -r 10\n\n# Generate a realistic full day of restaurant operations\n./bin/simulate day\n\n# Generate a busy day (2x normal volume)\n./bin/simulate day -x 2.0\n\n# Generate a slow day (0.5x normal volume)\n./bin/simulate day -x 0.5\n\n# Generate a lunch or dinner rush\n./bin/simulate rush -p lunch -n 20\n./bin/simulate rush -p dinner -n 30\n\n# Run full simulation (setup + orders)\n./bin/simulate full\n\n# Check current status (all entities)\n./bin/simulate status\n\n# Use a specific merchant by index or ID\n./bin/simulate status -i 0\n./bin/simulate generate -m YOUR_MERCHANT_ID\n\n# Gift card operations\n./bin/simulate gift_cards                    # List all gift cards\n./bin/simulate gift_card_create -a 5000      # Create $50 gift card\n./bin/simulate gift_card_balance -i CARD_ID  # Check balance\n./bin/simulate gift_card_reload -i CARD_ID -a 2500  # Add $25\n./bin/simulate gift_card_redeem -i CARD_ID -a 1000  # Use $10\n\n# Refund operations\n./bin/simulate refunds                       # List all refunds\n./bin/simulate refund -p PAYMENT_ID          # Full refund\n./bin/simulate refund -p PAYMENT_ID -a 500   # Partial refund ($5)\n\n# Inventory \u0026 Modifiers\n./bin/simulate modifier_groups               # List modifier groups\n./bin/simulate tax_rates                     # List tax rates\n\n# Order Types \u0026 Service Charges\n./bin/simulate order_types                   # List order types (Dine In, Takeout, etc.)\n./bin/simulate service_charges               # List service charges\n\n# Shift Management\n./bin/simulate shifts                        # List active shifts\n./bin/simulate shift_clock_in -e EMP_ID      # Clock in an employee\n./bin/simulate shift_clock_out -e EMP_ID     # Clock out an employee\n\n# Cash Drawer Operations\n./bin/simulate cash_open_drawer -a 10000     # Open drawer with $100 starting cash\n./bin/simulate cash_close_drawer -e EMP_ID   # Close drawer for employee\n\n# List recent orders\n./bin/simulate orders\n./bin/simulate orders -l 50              # Show 50 orders\n\n# Reset orders (delete all orders, keep menu/employees)\n./bin/simulate reset_orders --confirm    # Delete today's orders\n./bin/simulate reset_orders --confirm --no-today-only  # Delete ALL orders\n\n# Delete all entities (requires confirmation)\n./bin/simulate delete --confirm\n\n# Enable verbose logging\n./bin/simulate generate -v\n```\n\n### Database Management\n\n```bash\n# Database subcommands\n./bin/simulate db create    # Create PostgreSQL database\n./bin/simulate db migrate   # Run pending migrations\n./bin/simulate db seed      # Seed with 9 business types, 38 categories, 168 items\n./bin/simulate db reset     # Drop, create, migrate, and seed\n\n# Reporting\n./bin/simulate summary         # Show daily summary (revenue, orders, tips, tax)\n./bin/simulate audit            # Show recent API requests\n./bin/simulate business_types   # List business types with category/item counts\n```\n\n## Business Types\n\nThe simulator supports 9 business types across 3 industries:\n\n| Business Type | Industry | Categories | Items | Description |\n|---------------|----------|------------|-------|-------------|\n| Restaurant | Food | 5 | 25 | Full-service casual dining |\n| Cafe/Bakery | Food | 5 | 25 | Coffee shop with pastries and light fare |\n| Bar/Nightclub | Food | 5 | 25 | Craft cocktails, draft beer, late-night bites |\n| Food Truck | Food | 3 | 15 | Mobile street food — tacos and Mexican fare |\n| Fine Dining | Food | 3 | 15 | Upscale prix-fixe and a la carte dining |\n| Pizzeria | Food | 3 | 15 | Classic and specialty pies, calzones, sides |\n| Retail Clothing | Retail | 5 | 25 | Casual wear with size/color variants |\n| Retail General | Retail | 5 | 13 | Electronics, home goods, personal care |\n| Salon/Spa | Service | 4 | 10 | Hair salon, spa treatments, nail services |\n\nAll business types have tailored order profiles, category structures, and item pricing.\n\n## Menu Structure\n\n### Categories (Restaurant Example)\n- Appetizers\n- Entrees\n- Sides\n- Desserts\n- Drinks\n- Alcoholic Beverages\n- Specials\n\n### Sample Items\n\n| Category | Item | Price |\n|----------|------|-------|\n| Appetizers | Buffalo Wings | $12.99 |\n| Appetizers | Loaded Nachos | $10.99 |\n| Entrees | Classic Burger | $14.99 |\n| Entrees | NY Strip Steak | $28.99 |\n| Entrees | Grilled Salmon | $21.99 |\n| Sides | French Fries | $4.99 |\n| Desserts | Cheesecake | $7.99 |\n| Drinks | Soft Drink | $2.99 |\n| Alcoholic | Draft Beer | $5.99 |\n\n### Modifier Groups\n\n| Group | Options | Example Use |\n|-------|---------|-------------|\n| Temperature | Rare, Medium Rare, Medium, Medium Well, Well Done | Steaks, Burgers |\n| Add-Ons | Extra Cheese (+$1.50), Bacon (+$2.00), Avocado (+$1.75) | Burgers, Sandwiches |\n| Side Choice | French Fries, Sweet Potato Fries, Onion Rings, Salad | Entrees |\n| Dressing | Ranch, Blue Cheese, Caesar, Balsamic, Honey Mustard | Salads |\n| Drink Size | Small, Medium, Large | Beverages |\n\n## Payment Methods\n\n### Credit/Debit Card Payments (Ecommerce API)\n\nCredit and debit card payments are fully supported via the **Clover Ecommerce API**. This requires configuring `PUBLIC_TOKEN` and `PRIVATE_TOKEN` in your `.env.json`.\n\n~55% of orders use card payments when the Ecommerce API is configured. The simulator tokenizes test cards and creates charges linked to orders. If a charge fails, payment gracefully falls back to cash.\n\n**Test Card Numbers:**\n\n| Card Type | Number |\n|-----------|--------|\n| Visa | 4242424242424242 |\n| Visa Debit | 4005562231212123 |\n| Mastercard | 5200828282828210 |\n| Amex | 378282246310005 |\n| Discover | 6011111111111117 |\n| Decline (test) | 4000000000000002 |\n| Insufficient Funds (test) | 4000000000009995 |\n\n**Ecommerce API Endpoints:**\n- Tokenization: `https://token-sandbox.dev.clover.com/v1/tokens`\n- Charges: `https://scl-sandbox.dev.clover.com/v1/charges`\n- Refunds: `https://scl-sandbox.dev.clover.com/v1/refunds`\n\n### Platform API Tenders\n\nFor non-card payments, the simulator uses Platform API tenders:\n- Cash (preferred for orders under $20)\n- Check\n- Gift Card\n- External Payment\n\nThe simulator uses whatever tenders are available in the Clover merchant account. Card tenders are automatically excluded from split payments (which use the Platform API).\n\n## Audit Trail \u0026 Persistence\n\nThe simulator persists all activity to a PostgreSQL database for analysis and debugging:\n\n### Models\n\n| Model | Purpose |\n|-------|---------|\n| `BusinessType` | 9 business types with industry classification and order profiles |\n| `Category` | 38 categories linked to business types with tax groups |\n| `Item` | 168 items with SKUs, pricing, and optional size/color variants |\n| `SimulatedOrder` | Every generated order with merchant ID, period, dining option, amounts |\n| `SimulatedPayment` | Payment records with tender type classification (credit_card, debit_card, cash, check, gift_card) |\n| `ApiRequest` | Full audit log of every HTTP call to Clover (method, URL, status, duration, payloads) |\n| `DailySummary` | Automated daily aggregation of revenue, tax, tips, and discounts |\n\n### Daily Summary\n\nThe `DailySummary` model automatically aggregates:\n- Order count, revenue, tax, tips, discounts\n- Breakdown by meal period and dining option\n- Revenue by meal period and dining option\n- Payment breakdown by tender type\n\n```ruby\n# Generate a summary for today\nDailySummary.generate_for!(\"MERCHANT_ID\", Date.today)\n\n# Query summaries\nDailySummary.for_merchant(\"M1\").recent(7)\nDailySummary.between_dates(1.week.ago, Date.today)\n```\n\n## Tax Rates\n\nThe simulator supports per-item tax rates based on category:\n\n| Category | Tax Rate | Notes |\n|----------|----------|-------|\n| Food Items | 8.25% | Standard sales tax |\n| Alcoholic Beverages | 8.25% + 10% | Sales tax + alcohol tax |\n\nTax rates are automatically assigned to items during setup based on their category.\n\n## Service Charges\n\n### Auto-Gratuity\n\nLarge parties (6+ guests) automatically receive an 18% auto-gratuity service charge. This is:\n- Added to the order subtotal before payment\n- Displayed as a separate line item\n- Configurable via the `ServiceChargeService`\n\n**Note:** Service charges must be pre-configured in the Clover dashboard for sandbox environments, as the API may not support creating them dynamically.\n\n## Order Types\n\nThe simulator supports multiple order types that affect order flow and reporting:\n\n| Order Type | Description |\n|------------|-------------|\n| Dine In | In-restaurant dining |\n| Takeout | Customer pickup |\n| Delivery | Delivery orders |\n| Online | Online/web orders |\n| Catering | Large catering orders |\n\nOrder types are automatically created during setup if they don't exist.\n\n## Tips\n\nTips vary by dining option to simulate realistic customer behavior:\n\n| Dining Option | Min Tip | Max Tip |\n|---------------|---------|---------|\n| Dine-In (HERE) | 15% | 25% |\n| To-Go | 0% | 15% |\n| Delivery | 10% | 20% |\n\n- Large parties (6+) automatically receive 18% auto-gratuity\n- Split payments divide tips proportionally across tenders\n\n## Order Patterns\n\n### Daily Volume\n\n| Day | Min Orders | Max Orders |\n|-----|------------|------------|\n| Weekday | 40 | 60 |\n| Friday | 70 | 100 |\n| Saturday | 80 | 120 |\n| Sunday | 50 | 80 |\n\n### Meal Periods\n\nOrders are distributed across realistic meal periods with weighted distribution:\n\n| Period | Hours | Weight | Avg Items | Avg Party Size |\n|--------|-------|--------|-----------|----------------|\n| Breakfast | 7-10 AM | 15% | 2-4 | 1-2 |\n| Lunch | 11 AM-2 PM | 30% | 2-5 | 1-4 |\n| Happy Hour | 3-5 PM | 10% | 2-4 | 2-4 |\n| Dinner | 5-9 PM | 35% | 3-6 | 2-6 |\n| Late Night | 9-11 PM | 10% | 2-4 | 1-3 |\n\n### Dining Options\n\nEach meal period has different dining option distributions:\n\n| Period | Dine-In | To-Go | Delivery |\n|--------|---------|-------|----------|\n| Breakfast | 40% | 50% | 10% |\n| Lunch | 35% | 45% | 20% |\n| Happy Hour | 80% | 15% | 5% |\n| Dinner | 70% | 15% | 15% |\n| Late Night | 50% | 30% | 20% |\n\n## Architecture\n\n```\nclover_sandbox_simulator/\n├── bin/simulate                      # CLI entry point (Thor)\n├── lib/\n│   ├── clover_sandbox_simulator.rb   # Gem entry point, VERSION constant\n│   └── clover_sandbox_simulator/\n│       ├── configuration.rb          # Multi-merchant config from .env.json\n│       ├── database.rb               # PostgreSQL connection management\n│       ├── seeder.rb                 # Idempotent FactoryBot seeder\n│       ├── parallel_executor.rb      # Concurrent execution support\n│       ├── models/                   # ActiveRecord models (standalone, no Rails)\n│       │   ├── record.rb            # Base class for all models\n│       │   ├── business_type.rb     # 9 business types with industries\n│       │   ├── category.rb          # 38 categories per business type\n│       │   ├── item.rb              # 168 items with pricing \u0026 variants\n│       │   ├── simulated_order.rb   # Generated order audit records\n│       │   ├── simulated_payment.rb # Payment audit records by tender type\n│       │   ├── api_request.rb       # Full HTTP request/response audit log\n│       │   └── daily_summary.rb     # Automated daily aggregation\n│       ├── db/\n│       │   ├── migrate/             # 8 PostgreSQL migrations (UUID PKs)\n│       │   └── factories/           # FactoryBot factories (shared with seeder)\n│       ├── services/\n│       │   ├── base_service.rb      # HTTP client, error handling, audit logging\n│       │   └── clover/              # Clover API services\n│       │       ├── inventory_service.rb    # Categories, items, modifier groups\n│       │       ├── order_service.rb        # Orders, line items, modifiers\n│       │       ├── payment_service.rb      # Payments, splits, card payments\n│       │       ├── tender_service.rb       # Payment tenders, card detection\n│       │       ├── ecommerce_service.rb    # Card tokenization \u0026 charges\n│       │       ├── tax_service.rb          # Tax rates, per-item taxes\n│       │       ├── discount_service.rb     # Discounts, promos, combos, loyalty\n│       │       ├── employee_service.rb     # Employee management\n│       │       ├── customer_service.rb     # Customer management\n│       │       ├── refund_service.rb       # Full/partial refunds\n│       │       ├── gift_card_service.rb    # Gift card management\n│       │       ├── service_charge_service.rb # Service charges, auto-gratuity\n│       │       ├── shift_service.rb        # Employee shifts, clock in/out\n│       │       ├── order_type_service.rb   # Order types (Dine In, Takeout, etc.)\n│       │       ├── cash_event_service.rb   # Cash drawer operations\n│       │       ├── oauth_service.rb        # Token refresh\n│       │       └── services_manager.rb     # Thread-safe service access\n│       ├── generators/\n│       │   ├── data_loader.rb        # DB-first data loading with JSON fallback\n│       │   ├── entity_generator.rb   # Setup entities (idempotent)\n│       │   └── order_generator.rb    # Generate realistic orders \u0026 payments\n│       └── data/\n│           └── restaurant/           # JSON data files (fallback for DB)\n│               ├── categories.json\n│               ├── items.json\n│               ├── discounts.json\n│               ├── tenders.json\n│               ├── modifiers.json\n│               └── tax_rates.json\n└── spec/                             # 1124 examples, 0 failures\n```\n\n## Development\n\n```bash\n# Run all tests\nbundle exec rspec\n\n# Run tests with documentation format\nbundle exec rspec --format documentation\n\n# Run specific test file\nbundle exec rspec spec/services/clover/tender_service_spec.rb\n\n# Run model specs\nbundle exec rspec spec/models/\n\n# Run integration tests (requires .env.json with valid credentials)\nbundle exec rspec spec/integration/\n\n# Run linter\nbundle exec rubocop\n\n# Open console\nbundle exec irb -r ./lib/clover_sandbox_simulator\n\n# Build the gem\ngem build clover_sandbox_simulator.gemspec\n```\n\n## Testing\n\nThe gem includes comprehensive RSpec tests with WebMock for HTTP stubbing, VCR for integration tests, and DatabaseCleaner for test isolation.\n\n### Test Coverage\n\n- **1124 examples, 0 failures, 3 pending**\n- Database connection management and migration\n- Seeder idempotency (9 business types, 38 categories, 168 items)\n- FactoryBot factory validation (219 factories/traits)\n- All ActiveRecord models (validations, scopes, associations)\n- All Clover API services:\n  - InventoryService (categories, items, modifier groups)\n  - OrderService (create, line items, dining options, modifiers)\n  - PaymentService (single, split, and card payments)\n  - TenderService (tender selection, card detection, ecommerce filtering)\n  - EcommerceService (tokenization, charges, refunds)\n  - TaxService (rates, per-item calculation, item associations)\n  - DiscountService (percentage, fixed, time-based, loyalty, combo, promo codes)\n  - EmployeeService (CRUD, deterministic setup)\n  - CustomerService (CRUD, anonymous orders)\n  - RefundService (full/partial refunds, multiple strategies)\n  - GiftCardService (create, reload, redeem)\n  - ServiceChargeService (auto-gratuity, apply to orders)\n  - ShiftService (clock in/out, active shifts)\n  - OrderTypeService (CRUD, default setup)\n  - CashEventService (drawer operations, simulated responses)\n  - ServicesManager (thread-safe memoization, lazy loading)\n- Audit trail (API request logging, order/payment tracking, daily summaries)\n- Order generator (meal periods, dining options, tips, card payments, fallbacks, refunds, modifiers, service charges)\n- Data loader (DB-first with JSON fallback, format parity)\n- Multi-business type integration (industry classification, order profiles)\n- Financial data quality validation\n- Edge cases (nil handling, empty arrays, API errors, network failures)\n- VCR integration tests for real API validation\n\n### Test Files\n\n```\nspec/\n├── audit_logging_spec.rb              # BaseService audit + OrderGenerator tracking\n├── configuration_spec.rb              # Multi-merchant config validation\n├── configuration_database_url_spec.rb # DATABASE_URL parsing\n├── database_spec.rb                   # Connection management, migrations\n├── seeder_spec.rb                     # Idempotent seeding, business types\n├── factories/\n│   └── factories_spec.rb             # 219 factory/trait validation\n├── generators/\n│   ├── data_loader_spec.rb           # DB/JSON loading, format parity\n│   ├── entity_generator_spec.rb      # Idempotent setup\n│   └── order_generator_spec.rb       # Payments, tips, dining, card flow\n├── integration/\n│   ├── audit_trail_spec.rb           # End-to-end order/payment/summary\n│   ├── data_loader_compat_spec.rb    # DB vs JSON compatibility\n│   ├── multi_business_spec.rb        # 9 business types, industries\n│   ├── modifier_groups_spec.rb       # VCR: real API\n│   ├── service_charges_spec.rb       # VCR: real API\n│   ├── order_types_spec.rb           # VCR: real API\n│   ├── cash_events_spec.rb           # VCR: real API\n│   └── tax_rates_spec.rb            # VCR: real API\n├── models/\n│   ├── api_request_spec.rb           # Scopes, validations\n│   ├── business_type_spec.rb         # Industries, associations\n│   ├── category_spec.rb              # Scoped uniqueness\n│   ├── daily_summary_spec.rb         # Aggregation, idempotency\n│   ├── item_spec.rb                  # Pricing, variants, scopes\n│   ├── record_spec.rb                # Base class\n│   ├── simulated_order_spec.rb       # Status transitions, scopes\n│   └── simulated_payment_spec.rb     # Tender classification, scopes\n└── services/clover/\n    ├── cash_event_service_spec.rb\n    ├── customer_service_spec.rb\n    ├── discount_service_spec.rb\n    ├── employee_service_spec.rb\n    ├── financial_data_quality_spec.rb\n    ├── gift_card_service_spec.rb\n    ├── inventory_service_spec.rb\n    ├── order_service_spec.rb\n    ├── order_type_service_spec.rb\n    ├── payment_service_spec.rb\n    ├── refund_service_spec.rb\n    ├── service_charge_service_spec.rb\n    ├── services_manager_spec.rb\n    ├── shift_service_spec.rb\n    ├── tax_service_spec.rb\n    └── tender_service_spec.rb\n```\n\n### Idempotency Verification\n\nAll setup operations are idempotent - running them multiple times will not create duplicates:\n\n```ruby\n# This is safe to run multiple times\ngenerator = CloverSandboxSimulator::Generators::EntityGenerator.new\ngenerator.setup_all # First run: creates entities\ngenerator.setup_all # Second run: skips existing, returns same results\n```\n\nThe tests verify:\n- Categories are not duplicated (case-insensitive matching)\n- Items are not duplicated (case-insensitive matching)\n- Discounts are not duplicated (case-insensitive matching)\n- Modifier groups AND their child modifiers are not duplicated\n- Tax rates are not duplicated\n- Order types are not duplicated\n- Employees/customers only created if count threshold not met\n- Database seeder is idempotent across all 9 business types\n\n## Sandbox Limitations\n\nSome Clover sandbox operations may return errors or behave differently than production:\n\n| Feature | Sandbox Support | Notes |\n|---------|-----------------|-------|\n| Service Charge Creation | Limited | Must pre-configure in dashboard |\n| Cash Event Creation | Limited | Returns 405, simulated locally |\n| Item Tax Rate Fetch | Limited | Returns 405, simulated locally |\n| Credit Card Payments | Full | Via Ecommerce API |\n| Order Creation | Full | Today's date only |\n\nThe simulator handles these limitations gracefully with fallback behavior.\n\n## Clover API Notes\n\n- **Sandbox URL**: `https://sandbox.dev.clover.com/`\n- **API Version**: v3\n- **Authentication**: Bearer token (OAuth) for Platform API; apikey header for tokenization\n- **Date Limitation**: Clover sandbox only allows creating orders for TODAY\n- **Ecommerce API**: Separate endpoints for card tokenization, charges, and refunds\n\n## License\n\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdan1d%2Fclover_sandbox_simulator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdan1d%2Fclover_sandbox_simulator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdan1d%2Fclover_sandbox_simulator/lists"}