PhoenixRooivalk is a dual-brand modular counter-UAS (counter-drone) defense platform. SkySnare targets consumer sports/training; AeroNet targets AI-enabled enterprise infrastructure security. The system combines blockchain-based evidence anchoring, edge AI processing, and a threat simulation engine.
This is a simulation/gameplay system for testing and training purposes.
| Layer | Technology |
|---|---|
| Frontend | Next.js 16, React 19, Docusaurus 3, Leptos/WASM, Tauri 2 |
| Backend | Rust (Axum 0.8), Python 3.9+ (detector) |
| Blockchain | Solana SDK, EtherLink, x402 payment protocol |
| Database | SQLite via SQLx, Azure Cosmos DB (Docs) |
| Package Mgr | pnpm 10.31.0 (enforced via corepack) |
| Monorepo | Turborepo 2.8 |
| JS Testing | Vitest (marketing), Jest (docs, ui) |
| Rust Testing | cargo test |
| Python Testing | pytest |
| JS Linting | ESLint 9, Prettier 3.8 |
| Rust Linting | Clippy, cargo fmt |
| Python Linting | Ruff, Black, isort, mypy, bandit (pre-commit) |
| CI/CD | GitHub Actions, Azure Static Web Apps |
| Styling | Tailwind CSS 4.1, CSS Modules |
| Infrastructure | Azure Bicep, Terraform (ML training) |
apps/
marketing/ # Next.js 16 marketing website
docs/ # Docusaurus 3 docs + Azure Functions
api/ # Rust Axum REST API
keeper/ # Rust blockchain keeper service
evidence-cli/ # Rust CLI for evidence hashing
detector/ # Python drone detection
threat-simulator-desktop/ # Tauri 2 + Leptos WASM
crates/
evidence/ # Core evidence logging, SHA-256
anchor-solana/ # Solana blockchain anchoring
anchor-etherlink/# EtherLink blockchain anchoring
address-validation/ # Blockchain address validation
phoenix-common/ # Shared Rust DB utilities
x402/ # HTTP 402 payment protocol
packages/
types/ # Shared TypeScript types
ui/ # Shared React components
utils/ # Shared utility functions
config/ # Tooling configs (canonical here; some inlined at root for CI)
scripts/ # Deployment and utility scripts
infra/ # IaC: azure/ (Bicep), terraform/
tools/ # pdf_generator (Python CLI)
e2e/ # Playwright end-to-end tests
# Install dependencies
pnpm install
# Build
pnpm build # All JS/TS apps via Turborepo
pnpm --filter marketing build # Single app (runs sync:wasm first)
pnpm --filter docs build # Docs site
cargo build # Rust workspace
# Dev servers
pnpm dev # All apps
pnpm --filter marketing dev # Marketing on :3000
pnpm --filter docs start # Docs on :3000
pnpm sim:dev # Threat simulator on :8080
pnpm sim:dev:tauri # Full desktop app
# Test
pnpm --filter marketing test # Marketing tests (Vitest)
pnpm --filter docs test # Docs tests (Jest)
pnpm --filter ui test # UI package tests (Jest)
cargo test # All Rust tests
pnpm sim:test # Threat simulator tests
pytest apps/detector # Python tests
pytest apps/detector -m "not slow and not hardware"
# Lint & Format
pnpm lint # ESLint
pnpm typecheck # TypeScript
pnpm format # Prettier write
pnpm format:check # Prettier check
cargo clippy -- -D warnings # Rust lint
cargo fmt --all # Rust format
cargo fmt --all -- --check # Rust format check
pnpm fx # Combined: format + lint
# Python linting (in apps/detector/)
ruff check src/ # Fast Python linter
black --check src/ # Format check
isort --check-only src/ # Import order check
mypy src/ # Type checking
# Desktop threat simulator
pnpm sim:build:tauri # Build release
pnpm sim:test # Run simulator tests
pnpm sim:lint # Clippy on simulatorKey routes:
GET/POST /evidence— Evidence job managementGET /evidence/{id}— Individual evidence lookupGET/POST /countermeasures— Counter-drone deploymentsGET/POST /signal-disruptions— RF disruption trackingGET/POST /jamming-operations— EW operationsPOST /auth/login,GET /auth/me,PUT /auth/profilePOST /career/apply— Career applicationsPOST /admin/seed-team-members— Seed fixture dataGET /health— Health checkPOST /api/v1/evidence/verify-premium— x402 premiumGET /api/v1/x402/status— Payment protocol statusGET/POST /preorders— Preorder managementGET /preorders/{id}— Individual preorder lookup
Database: SQLite with automatic migrations on startup. Foreign keys enforced. DB
URL priority: API_DB_URL > KEEPER_DB_URL > hardcoded default. Pagination:
Default 10 items/page, max 100. x402 payment protocol: disabled by default, set
X402_ENABLED=true to enable.
Processes blockchain anchoring jobs from an outbox database. Dual-loop: job processing + transaction confirmation polling.
Environment variables:
KEEPER_PROVIDER=stub— Provider selection:stub/etherlink/solana/multiKEEPER_DB_URL=sqlite://blockchain_outbox.sqlite3KEEPER_POLL_MS=5000— Job polling intervalKEEPER_CONFIRM_POLL_MS=30000— Confirmation polling intervalKEEPER_HTTP_PORT=8081— HTTP health check portKEEPER_USE_STUB=false— Legacy; preferKEEPER_PROVIDERETHERLINK_ENDPOINT,ETHERLINK_NETWORK,ETHERLINK_PRIVATE_KEY
- Build requires WASM sync:
pnpm --filter marketing sync:wasmruns automatically beforenext build - Email-based auth (no passwords), session via localStorage
- Team member detection prevents self-applications
- Env:
NEXT_PUBLIC_API_URL,NEXT_PUBLIC_ENABLE_TOUR_SKIP,NEXT_PUBLIC_TOUR_AUTO_START
- Has its own Azure Functions backend in
azure-functions/(Node 20, Jest tests) - Azure Entra ID (B2C) authentication
- Comment system backed by Azure Cosmos DB
- PWA offline support, Mermaid diagrams, local search
- Env:
CLOUD_PROVIDER,AZURE_ENTRA_CLIENT_ID,AZURE_ENTRA_TENANT_ID, plus more in.env.example
Platform-specific installation:
pip install -e ".[pi]" # Raspberry Pi (TFLite)
pip install -e ".[jetson]" # NVIDIA Jetson (ONNX)
pip install -e ".[desktop]" # Desktop (TensorFlow)
pip install -e ".[coral]" # Coral Edge TPU
pip install -e ".[dev]" # Development toolsModular architecture: pluggable cameras, inference engines, trackers via Factory
pattern. Hardware auto-detection selects appropriate backend. Run with
drone-detector CLI or python -m main.
Two development modes:
- Frontend only:
trunk serve --port 8080(WASM only) - Full desktop:
cargo tauri dev(includes Tauri backend)
Requires: Rust, wasm32-unknown-unknown target, Trunk, Tauri CLI. Linux build
deps: libwebkit2gtk-4.1-dev, build-essential, libssl-dev,
libayatana-appindicator3-dev.
# Hash a payload locally
cargo run -p evidence-cli -- --payload '{"event":"test"}'
# Hash and submit to API
cargo run -p evidence-cli -- \
--payload @file.json --submit \
--api-url http://localhost:8080- All Rust crates use
rustlsinstead of native OpenSSL (RUSTSEC-2025-0004). Never addnative-tlsfeatures to reqwest or other HTTP clients. - Unsafe code is forbidden workspace-wide in Cargo.toml.
- Marketing build depends on WASM:
sync:wasmcopies compiled WASM from the threat simulator. If the simulator hasn't been built, marketing build will use a fallback. - pnpm workspace includes nested apps:
apps/*/*coversapps/docs/azure-functions/(src-tauri has no package.json, not a pnpm member). getrandomcrate requireswasm_jsfeature for WASM targets (configured in workspace Cargo.toml).- Config files: Canonical source is
config/. Root.prettierrc,.markdownlint.json, andcspell.jsonare inlined (not symlinked) for CI/Windows; editconfig/and sync to root when changing those. - Tauri desktop app has conditional compilation: WASM-only vs native deps
gated with
#[cfg(target_arch = "wasm32")]. - Rust CI builds require Linux GUI deps for Tauri (GTK, webkit, appindicator).
- Cargo audit runs in CI with
--ignore RUSTSEC-2023-0071(pending investigation). - Python mypy type errors are resolved — CI enforces mypy (no
continue-on-error).
- Strict mode TypeScript, avoid
any - Functional components with hooks (no class components)
- Named exports preferred over default exports
- CSS Modules for component styling (dark tactical theme)
- WCAG AA+ accessibility: ARIA labels, keyboard nav, 4.5:1
- ESLint security plugin enabled
- snake_case functions, PascalCase types
Result<T, E>with?operator, avoid panics- Doc comments on public APIs
- All clippy warnings must be resolved (deny warnings in CI)
- Unsafe code is forbidden (workspace setting)
- Use
rustlsfor all HTTP/TLS operations
- Type hints with pydantic v2
- Ruff for linting (E/W/F/I/B/C4/UP rules), Black for formatting (line-length 100)
- isort for import ordering (black profile)
- pytest markers:
slow,integration,hardware - bandit for security scanning
- 50% coverage target (not yet enforced in CI)
Use conventional commits:
feat: Add tactical grid overlay
fix: Resolve header gap spacing
docs: Update README with installation steps
refactor: Extract button variants
test: Add accessibility tests
perf: Optimize grid rendering
chore: Update dependencies
When creating ADRs, reference the template at:
apps/docs/docs/technical/architecture/adr-0000-template-and-guide.md
Numbering: 0001-0099 (Core), 0100-0199 (Security), 0200-0299 (Blockchain), 0300-0399 (AI/ML), 0400-0499 (Infrastructure & DevOps), D001-D999 (Dev Decisions).
Cross-package imports use workspace protocol:
"@phoenix-rooivalk/types": "workspace:*"
Shared Rust crates are referenced as path dependencies in workspace Cargo.toml.
See .env.example in each app for full details. Key variables:
| App | Variable | Purpose |
|---|---|---|
| Marketing | NEXT_PUBLIC_API_URL |
Backend API URL |
| Docs | CLOUD_PROVIDER |
azure or offline |
| Docs | AZURE_ENTRA_CLIENT_ID |
Azure AD B2C client |
| Docs | AZURE_FUNCTIONS_BASE_URL |
Functions URL |
| Keeper | KEEPER_PROVIDER |
stub for dev |
| Keeper | KEEPER_DB_URL |
SQLite connection |
| API | RUST_LOG |
Log level |
| API | API_DB_URL |
SQLite URL |
| API | X402_ENABLED |
Enable payment protocol |
| API | X402_WALLET_ADDRESS |
Solana wallet |
Never commit .env files.
Tooling configs live in config/. Edit files in config/; root copies are for
tool discovery.
- Symlinked from root:
.eslintrc.js,.prettierignore,.editorconfig,clippy.toml(where supported). - Inlined at root (for CI/Windows):
.prettierrc,.markdownlint.json,cspell.json. Canonical source isconfig/; sync to root when changing.
- Azure Bicep (
infra/azure/): Static Web Apps, Cosmos DB, Functions, Key Vault, App Insights, Notification Hubs. Environments: dev/prod. - Terraform (
infra/terraform/ml-training/): Azure ML workspace with GPU compute for YOLO drone detection model training. - Deployment scripts in
scripts/: Azure setup, Cosmos container creation, deployment validation, diagnostics.
Each app has its own CLAUDE.md with app-specific gotchas, commands, and
architecture details. These are loaded automatically when working in that
directory:
apps/api/CLAUDE.md— Routes, DB priority, x402 payment protocol, migrationsapps/keeper/CLAUDE.md— Dual-loop anchoring, providers, batch Merkle treesapps/docs/CLAUDE.md— Docusaurus, Azure Functions, build-time env varsapps/marketing/CLAUDE.md— Next.js static export, WASM sync, dual game enginesapps/detector/CLAUDE.md— Python config system, hardware platforms, lintingapps/threat-simulator-desktop/CLAUDE.md— WASM/native compilation, Trunk, Tauri