# Shopify App Pre-Approval Framework
A Rust-native agentic system that validates Shopify apps against official approval documentation. Provides comprehensive validation through CLI, REST API, and MCP server interfaces.
[](https://github.com/umerkhan95/shopify-app-approver/actions/workflows/ci.yml)
[](https://opensource.org/licenses/MIT)
---
## 🚀 Claude Code Plugin (Quick Start)
**Validate your Shopify apps directly from Claude Code with one command:**
```bash
claude plugins add github:umerkhan95/shopify-app-approver
```
Then just ask Claude:
- *"Check if my Shopify app is ready for the App Store"*
- *"Validate the webhook handlers"*
- *"What GDPR requirements am I missing?"*
The plugin **auto-activates** when it detects Shopify app patterns in your project.
📖 **[Full Plugin Documentation →](PLUGIN.md)**
---
## Features
- **Multi-Language Parsing**: Analyze JavaScript, TypeScript, Ruby, Python, and PHP using tree-sitter
- **Deep AST Analysis**: Detect complex patterns like API calls, webhooks, billing, and security operations
- **Cross-File Dependency Tracking**: Build dependency graphs, detect circular dependencies
- **Configuration Validation**: Validate `shopify.app.toml` including GDPR webhook requirements
- **Comprehensive Validation**: Check webhooks, API usage, billing, security, OAuth, and data protection
- **LLM-Powered Analysis**: GLM 4.7 primary with Claude fallback for deep semantic analysis
- **Circuit Breaker Pattern**: Automatic failover between LLM providers
- **Distributed Tracing**: OpenTelemetry support for observability
- **Multi-Tenant SaaS**: JWT authentication with tenant isolation
- **MCP Integration**: Lightweight tools for AI agents (Claude Code, Windsurf, OpenCode)
## Build Status
- **Tests**: 48 passing
- **Rust**: 1.75+ required
- **Platform**: Linux, macOS, Windows
## Quick Start
### Prerequisites
- Rust 1.75+ (tested with 1.93.0)
- SQLite 3.x (bundled via SQLx)
### Installation
```bash
# Clone the repository
git clone https://github.com/umerkhan95/shopify-app-approver.git
cd shopify-app-approver
# Copy environment configuration
cp .env.example .env
# Edit .env with your API keys
# Required: JWT_SECRET (min 32 chars)
# Optional: GLM_API_KEY, ANTHROPIC_API_KEY for LLM features
# Build the project
cargo build --release
```
### Running the API Server
```bash
# Set required environment variable
export JWT_SECRET="your-secret-key-at-least-32-characters"
# Run the API server
cargo run -p shopify-approver-api
# Server starts at http://localhost:3000
```
### Running the CLI
```bash
# Validate a Shopify app
cargo run -p shopify-approver-cli -- check ./path/to/app
# Search documentation
cargo run -p shopify-approver-cli -- docs search "GDPR webhooks"
# List validation rules
cargo run -p shopify-approver-cli -- rules list
```
### Running the MCP Server (for AI Agents)
```bash
# Build and run MCP server
cargo build --release -p shopify-approver-mcp-server
./target/release/shopify-mcp-server
# With RAG support (optional)
MISTRAL_API_KEY=your-key QDRANT_URL=http://localhost:6334 ./target/release/shopify-mcp-server
```
Configure in Claude Code (`~/.claude/settings.json`):
```json
{
"mcpServers": {
"shopify-pre-approval": {
"command": "/path/to/shopify-mcp-server"
}
}
}
```
Or install as a plugin (recommended):
```bash
claude plugins add github:umerkhan95/shopify-app-approver
```
## Architecture
```
shopify-app-approver/
├── crates/
│ ├── core/ # Shared types, traits, error handling
│ ├── parsers/ # Multi-language parsing (tree-sitter)
│ ├── validators/ # Rule engine with pattern matching
│ ├── vector/ # Qdrant client for semantic search
│ ├── db/ # SQLite database layer (SQLx)
│ ├── rig-agent/ # LLM orchestration with circuit breaker
│ ├── mcp-server/ # MCP protocol server
│ ├── cli/ # Command-line interface
│ ├── api/ # REST API (Axum) with OpenTelemetry
│ └── ingestion/ # Documentation crawler
├── rules/ # Validation rules (TOML)
├── migrations/ # Database migrations
└── tests/ # Integration tests
```
## API Endpoints
### Authentication
| POST | `/api/v1/auth/register` | Register new user/tenant |
| POST | `/api/v1/auth/login` | Login and get tokens |
| POST | `/api/v1/auth/refresh` | Refresh access token |
### Reviews
| GET | `/api/v1/reviews` | List reviews (tenant-scoped, paginated) |
| POST | `/api/v1/reviews` | Create review with validation |
| GET | `/api/v1/reviews/:id` | Get review details with finding counts |
| DELETE | `/api/v1/reviews/:id` | Delete review and cascade findings |
| GET | `/api/v1/reviews/:id/findings` | Get findings (ordered by severity) |
### Validation (Quick Checks)
| POST | `/api/v1/validate/file` | Validate single file |
| POST | `/api/v1/validate/webhooks` | Check GDPR webhooks |
| POST | `/api/v1/validate/api` | Check API compliance |
| POST | `/api/v1/validate/billing` | Check billing compliance |
| POST | `/api/v1/validate/security` | Security scan |
### Documentation & Search
| GET | `/api/v1/docs/search?q=query` | Semantic search (Qdrant) with static fallback |
| GET | `/api/v1/docs/rules` | List all validation rules |
| GET | `/api/v1/docs/rules/:id` | Get rule details |
| GET | `/api/v1/docs/ingestions` | List recent doc ingestion runs |
| GET | `/api/v1/docs/ingestions/latest` | Get latest ingestion status |
## Validation Rules
Rules are defined in TOML format under `rules/`:
| Webhooks | WH001-WH004 | GDPR webhook compliance |
| API | API001-API003 | GraphQL vs REST, scope validation |
| Billing | BIL001-BIL002 | Shopify Billing API requirements |
| Security | SEC001-SEC005 | HTTPS, HMAC, secrets detection |
| OAuth | OAUTH001-OAUTH003 | OAuth flow validation |
| Data | DATA001-DATA003 | Customer data protection |
## Environment Variables
| `JWT_SECRET` | Yes | JWT signing secret (min 32 chars) |
| `DATABASE_URL` | No | SQLite path (default: `sqlite:./data/approver.db`) |
| `API_HOST` | No | API host (default: `0.0.0.0`) |
| `API_PORT` | No | API port (default: `3000`) |
| `ALLOWED_ORIGINS` | No | CORS origins (default: localhost) |
| `GLM_API_KEY` | No | GLM 4.7 API key for LLM features |
| `ANTHROPIC_API_KEY` | No | Claude API key (fallback) |
| `OPENAI_API_KEY` | No | OpenAI API key for embeddings |
| `QDRANT_URL` | No | Qdrant server URL (default: `http://localhost:6333`) |
| `QDRANT_COLLECTION` | No | Qdrant collection name (default: `shopify_approval_docs`) |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | No | OpenTelemetry collector endpoint |
## MCP Server Tools
The MCP server provides lightweight tools for AI agents:
```json
{
"tools": [
"quick_check_file", // Validate single file (~50-100 tokens)
"check_webhooks", // GDPR webhook status (~30-50 tokens)
"check_api_usage", // GraphQL vs REST (~50 tokens)
"check_billing", // Billing compliance (~30-50 tokens)
"get_fix_hint", // Fix recommendation (~100 tokens)
"search_docs", // Search documentation (~200 tokens)
"approval_status" // Overall readiness (~100 tokens)
]
}
```
## Development
### Running Tests
```bash
# Run all tests
cargo test --workspace
# Run specific crate tests
cargo test -p shopify-approver-validators
# Run with logging
RUST_LOG=debug cargo test --workspace
```
### Code Quality
```bash
# Format code
cargo fmt
# Run linter
cargo clippy --workspace -- -D warnings
# Check compilation
cargo check --workspace
```
### Database Migrations
Migrations run automatically on API server startup. For manual control:
```bash
# Migrations are in migrations/ directory
# SQLite database is created at $DATABASE_URL path
```
## Security
- **Password Hashing**: Argon2 with secure defaults
- **JWT Tokens**: Access (1h) and refresh (7d) token rotation
- **Tenant Isolation**: All queries filtered by tenant_id
- **Rate Limiting**: DashMap-based concurrent rate limiting
- **Input Validation**: Size limits, format validation
- **CORS**: Configurable allowed origins
## Performance
- **SQLite with WAL**: Write-Ahead Logging for better concurrency
- **Circuit Breaker**: Automatic LLM failover (5 failures, 30s reset)
- **Inline Hints**: `#[inline]` on hot path functions
- **Bulk Inserts**: Transaction-based batch operations
- **Connection Pooling**: Configurable pool sizes
## Observability
OpenTelemetry tracing is built-in:
```bash
# Enable OTLP export
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
export OTEL_SERVICE_NAME=shopify-approver-api
# JSON logs for production
export LOG_FORMAT=json
```
## License
MIT License - see [LICENSE](LICENSE) for details.
## Contributing
1. Fork the repository
2. Create a feature branch
3. Run `cargo fmt` and `cargo clippy`
4. Submit a pull request
See [CLAUDE.md](CLAUDE.md) for development guidelines.