Skip to content

erimeilis/store

Repository files navigation

Store Logo

Store

Serverless inventory management on Cloudflare's edge

Built with Hono + Rust + React 19 β€’ Deployed on Cloudflare Workers

Version Deployed on Cloudflare Workers License: MIT


Why I Built This

There was a company. It sold it's own stuff, but also reselled products from various providers. Some of these providers have normal APIs, but most just give Excel files. Every damn time.

Someone had to manually load these XLS files into our billing system. It was a mess - inconsistent formats, human errors, no way to track what's in stock.

So I built Store. It's basically a "provider for providers" - a unified place where managers can add, edit, and track products from any source. Meanwhile, I just hit the API from our billing system and everything syncs automatically.

The best part? It runs on Cloudflare Workers. No servers to rent. No DevOps guy to hire. Just deploy and forget.

Could this be another WooCommerce? Probably. But I didn't build it to compete with anyone - I built it because solving real problems is fun, and Cloudflare's edge platform is a joy to work with.


πŸ—οΈ Architecture

  • πŸ”§ Backend API (TypeScript/Hono): RESTful API with OpenAPI documentation
  • πŸ¦€ Public API (Rust/worker-rs): High-performance public endpoints for external integrations
  • 🎨 Frontend (React 19 SSR): Dashboard with server-side rendering

πŸ› οΈ Tech Stack

Backend API: Hono β€’ TypeScript 5 β€’ Zod OpenAPI β€’ Prisma ORM

Public API: Rust β€’ worker-rs β€’ serde β€’ KV caching

Frontend: React 19 SSR β€’ Tailwind CSS v4 β€’ DaisyUI 5 β€’ Zustand

Authentication: Google OAuth β€’ API Tokens with permissions

Database & Storage: Cloudflare D1 (SQLite) β€’ Cloudflare R2 β€’ Cloudflare KV

Deployment: Cloudflare Workers (TypeScript + Rust via WASM)


πŸš€ Quick Start

πŸ“‹ Prerequisites

  • 🟒 Node.js 20+
  • πŸ”§ Wrangler CLI (npm install -g wrangler)
  • ☁️ Cloudflare account

⚑ Installation

git clone git@github.com:erimeilis/store.git
cd store
npm install && cd frontend && npm install && cd ..

πŸ’» Local Development

npm run dev          # Local D1 database
npm run dev:remote   # Remote preview D1 database

This starts three workers with:

The script automatically:

  • πŸ”„ Updates wrangler to latest version
  • πŸ” Scans and loads modules
  • βš™οΈ Generates configuration files
  • πŸš€ Starts both workers with shared database

Press Ctrl+C to stop both services.

πŸš€ Deployment

npm run deploy              # Deploy all workers (backend, public-api, frontend)
npm run deploy:api          # Deploy backend API only
npm run deploy:public-api   # Deploy Rust public API only
npm run deploy:admin        # Deploy frontend only

βš™οΈ Initial Configuration

The deployment script handles everything automatically. Just configure .env:

  1. Copy environment template:

    cp .env.example .env
  2. Set required values in .env:

    CLOUDFLARE_ACCOUNT_ID=your-account-id
    ZONE_NAME=yourdomain.com
    API_DOMAIN=api.yourdomain.com
    FRONTEND_DOMAIN=admin.yourdomain.com
    GOOGLE_CLIENT_ID=your-google-client-id
    GOOGLE_CLIENT_SECRET=your-google-client-secret
  3. Deploy (creates D1 databases, KV namespaces, applies migrations, seeds tokens, uploads secrets):

    wrangler login
    npm run deploy

That's it! The deploy script automatically:

  • Creates D1 databases if they don't exist
  • Ensures KV namespaces are configured
  • Applies all database migrations
  • Seeds authentication tokens
  • Uploads secrets to Cloudflare
  • Deploys all workers

First user to login becomes admin automatically.


πŸ”§ Commands

πŸ’» Development

npm run dev                    # Local D1 database
npm run dev:remote             # Remote preview D1 database

πŸš€ Deployment

npm run deploy              # Deploy all workers
npm run deploy:api          # Deploy backend API only
npm run deploy:public-api   # Deploy Rust public API only
npm run deploy:admin        # Deploy frontend only

πŸ’Ύ Database Management

tsx scripts/db-reset.ts local       # Reset local D1
tsx scripts/db-reset.ts preview     # Reset preview D1
tsx scripts/db-reset.ts production  # Reset production D1 (with confirmation)

πŸ” Quality

npm run build                  # Type check backend
npm run test                   # Run tests (Vitest)
npm run test:run               # Run tests once

cd admin
npm run type-check             # Type check frontend
npm run lint                   # Run ESLint
npm run lint:fix               # Auto-fix lint issues

πŸ§ͺ Performance Testing

# Flood tests for load testing
npx tsx scripts/flood-test.ts --preset=public --rps=50 --duration=10

# A/B comparison: Rust vs TypeScript
npx tsx scripts/ab-test.ts --env=local
npx tsx scripts/ab-test.ts --env=production

✨ Features

πŸ“Š Dynamic Tables

  • βœ… Create any table structure on the fly
  • βœ… 17+ column types (text, number, date, boolean, email, url, phone, country, etc.)
  • βœ… Column validation and constraints
  • βœ… Required fields and default values
  • βœ… Inline editing with type-aware inputs
  • βœ… Mass actions: delete, set column value (with validation)
  • βœ… Table cloning with data

🧩 Module System

Extend Store with JSON-based modules - no code execution, just pure configuration:

  • βœ… Custom Column Types: Define new column types with validation, formatting, and data sources
  • βœ… External API Integration: Fetch entities from any external API (providers, catalogs, inventories)
    • Bearer, Basic, and custom header authentication
    • Response mapping with JSON path selectors
    • Configurable caching (5m to 7d)
    • Settings references for dynamic configuration
  • βœ… Table Generators: Auto-generate tables with predefined schemas and fake data
  • βœ… Built-in Types: Phone numbers, multiselect with grouped options, and more
  • βœ… KV Caching: All external API responses are cached in Cloudflare KV
  • βœ… Admin UI: Install, configure, and manage modules from the dashboard

Example: Fetch products from external provider API

{
  "source": {
    "type": "api",
    "endpoint": "$settings.providerApiUrl/products",
    "auth": { "type": "bearer", "token": "$settings.apiToken" },
    "responseSchema": { "dataPath": "data.items" },
    "valueField": "sku",
    "labelField": "name",
    "cache": "1h"
  }
}

πŸ›’ Sale Tables

  • βœ… Protected price and qty columns
  • βœ… Item purchasing workflow via API
  • βœ… Sales transaction tracking
  • βœ… Inventory management with audit trail

🏠 Rental Tables

  • βœ… Protected price, fee, used, available columns
  • βœ… Rental periods: hourly, daily, weekly, monthly, yearly
  • βœ… Rent and release workflows via API
  • βœ… Availability management

πŸ“₯ Data Import

  • βœ… Import from Excel (XLS, XLSX)
  • βœ… Import from CSV
  • βœ… Import from Google Sheets
  • βœ… Column mapping with auto-detection
  • βœ… Preview before import
  • βœ… Data validation with error reporting

πŸ” Authentication & Authorization

  • βœ… Google OAuth for dashboard
  • βœ… API tokens with read/write permissions
  • βœ… IP whitelist for tokens
  • βœ… Domain restrictions
  • βœ… Email-based access control

πŸ”Œ Public API

  • βœ… RESTful API with OpenAPI/Swagger docs
  • βœ… Bearer token authentication
  • βœ… Public endpoints for integrations
  • βœ… Purchase and rental operations
  • βœ… Search and filtering with pagination

πŸ“‘ API Endpoints

# Tables
GET    /api/tables                    # List all tables
POST   /api/tables                    # Create table
GET    /api/tables/:id                # Get table with columns
PUT    /api/tables/:id                # Update table
DELETE /api/tables/:id                # Delete table

# Columns
GET    /api/tables/:id/columns        # List columns
POST   /api/tables/:id/columns        # Add column
PATCH  /api/tables/:id/columns/:colId # Update column
DELETE /api/tables/:id/columns/:colId # Delete column

# Data
GET    /api/tables/:id/data           # List rows (paginated)
POST   /api/tables/:id/data           # Add row
PUT    /api/tables/:id/data/:rowId    # Update row
DELETE /api/tables/:id/data/:rowId    # Delete row
POST   /api/tables/:id/data/mass      # Mass actions (delete, set_field_value)

# Validation
GET    /api/tables/:id/validate       # Validate all rows
DELETE /api/tables/:id/invalid-rows   # Delete invalid rows

# Import
POST   /api/tables/:id/parse-import-file   # Parse XLS/CSV
POST   /api/tables/:id/parse-google-sheets # Parse Google Sheets
POST   /api/tables/:id/import-data         # Import with mapping

# Public (for integrations)
GET    /api/public/tables             # List public tables
GET    /api/public/tables/:id/items   # Get items
POST   /api/public/buy                # Purchase items
POST   /api/public/rent               # Rent items
POST   /api/public/release            # Release rented items

# Auth header
Authorization: Bearer YOUR_TOKEN

πŸ“ Project Structure

/
β”œβ”€β”€ πŸ”§ api/                    # Backend TypeScript API
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ routes/            # API route handlers
β”‚   β”‚   β”œβ”€β”€ services/          # Business logic layer
β”‚   β”‚   β”œβ”€β”€ repositories/      # Data access layer
β”‚   β”‚   β”œβ”€β”€ middleware/        # Auth & validation
β”‚   β”‚   β”œβ”€β”€ types/             # TypeScript definitions
β”‚   β”‚   └── utils/             # Utility functions
β”‚   β”œβ”€β”€ prisma/                # Database schema & migrations
β”‚   └── wrangler.toml          # Backend deployment config
β”œβ”€β”€ πŸ¦€ public-api/             # Rust high-performance API
β”‚   β”œβ”€β”€ src/                   # Rust source code
β”‚   β”œβ”€β”€ Cargo.toml             # Rust dependencies
β”‚   └── wrangler.toml          # Rust worker config
β”œβ”€β”€ 🎨 admin/                  # React SSR frontend
β”‚   └── src/
β”‚       β”œβ”€β”€ app/               # Page components
β”‚       β”œβ”€β”€ components/        # UI components
β”‚       β”œβ”€β”€ handlers/          # SSR route handlers
β”‚       └── lib/               # Client utilities
β”œβ”€β”€ 🧩 modules/                # Extension modules (JSON)
β”œβ”€β”€ 🌱 seeds/                  # Test data generators
β”œβ”€β”€ πŸ“œ scripts/                # Build, deploy & test scripts
β”‚   β”œβ”€β”€ deploy.js              # Deployment orchestration
β”‚   β”œβ”€β”€ flood-test.ts          # Load testing
β”‚   └── ab-test.ts             # A/B performance comparison
└── πŸ§ͺ test/                   # Test suites

πŸ—„οΈ Database Schema

Migrations are located in prisma/migrations/:

Migration Description
001_auth Users, sessions, tokens, allowed emails
002_dynamic_tables User tables, columns, data
004_commerce Sales, inventory transactions, rentals
005_ecommerce_settings Product ID column, rental periods
006_token_admin Token metadata and permissions
007_modules Installed modules tracking

πŸ”§ Troubleshooting

Port conflicts:

# Ports are automatically cleared by dev scripts, but if needed:
lsof -ti:5173 | xargs kill -9  # Frontend
lsof -ti:8787 | xargs kill -9  # Backend
lsof -ti:8788 | xargs kill -9  # Rust public API

Database issues:

npm run db:reset:local    # Clear and reset local database

Clean rebuild:

rm -rf node_modules admin/node_modules
npm install && cd admin && npm install

Rust worker build issues:

cd public-api
worker-build --release   # Rebuild Rust worker

πŸ”’ WAF Configuration

When deploying to production with Cloudflare WAF enabled, you may need to adjust security settings:

  • Rate Limiting: Configure appropriate rate limits for API endpoints
  • Bot Protection: Whitelist legitimate API consumers
  • Security Rules: Review managed rules that may block legitimate API traffic
  • IP Access Rules: Configure trusted IP ranges for monitoring/testing

Note: WAF rules should be reviewed and adjusted based on your specific traffic patterns and security requirements.


πŸ—ΊοΈ Roadmap

  • Billing System - Invoice generation, payment tracking, billing cycles
  • Webhooks for external integrations
  • Advanced analytics dashboard
  • Custom field validators via modules
  • Export to Excel/CSV

πŸ™ Acknowledgments

⚑ Core Technologies

πŸ› οΈ Development Tools

🎨 UI & Styling


πŸ“„ License

MIT License - see LICENSE file for details.


Made with πŸ’™πŸ’› using Hono, Rust, and Cloudflare Workers

About

Store system with buy-rent support via REST API

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors