npx agentspec-cli install e1cda2db-e908-4151-ae4f-f318cd230f83 --file-type clinerules→ .clinerules/
# Claude Code Rules for ranx.cloud (n8n-host)
## Project Overview
This is a managed SaaS platform for hosting n8n workflow automation instances on Kubernetes. The platform provides automated provisioning, DNS management via Cloudflare, and billing integration.
**Repository:** github.com/aliuygur/n8n-saas-api
**Brand:** ranx.cloud (formerly instol.cloud)
## Tech Stack
### Primary Language
- **Go 1.24+** (using toolchain go1.24.5)
- Standard library with Go 1.22+ HTTP routing features
### Template Engine & Frontend
- **templ** (v0.3.960) - Type-safe Go templating for HTML
- Templates: `internal/handler/components/*.templ`
- Generated files: `*_templ.go` (committed to git)
- **HTMX** (v1.9.10) for dynamic interactions
- **TailwindCSS** (CDN) for styling
- Vanilla JavaScript for interactive components
- No frontend build step required
### Database
- **PostgreSQL** with pgx/v5 driver
- **SQLC v2** for type-safe SQL query generation
- SQL files: `internal/db/queries/*.sql`
- Generated code: `internal/db/*.go` (committed to git)
- Run `make sqlc` after modifying SQL queries
- Migrations in `migrations/` directory
### Infrastructure
- **Kubernetes** (client-go v0.28.4) for orchestration
- **GKE Autopilot** for hosting
- **Cloudflare** for DNS and Tunnel management
- **Distroless containers** (gcr.io/distroless/static-debian12)
### Key Dependencies
- `samber/lo` (v1.52.0) - Functional utilities
- `golang-jwt/jwt/v5` - JWT authentication
- `golang.org/x/oauth2` - Google OAuth2
- `joho/godotenv` - Environment configuration
## Architecture Patterns
### Layered Architecture
```
Handler Layer (HTTP) → Service Layer (Business Logic) → Database Layer (SQLC)
```
- **Handlers** (`internal/handler/`) - HTTP request handling, templ rendering
- **Services** (`internal/services/`) - Business logic, transactions, orchestration
- **Database** (`internal/db/`) - SQLC-generated type-safe queries
- **Packages** (`pkg/`) - Reusable utilities
### Key Patterns
- Repository pattern via SQLC
- Saga pattern for complex operations (instance creation)
- Context-based dependency injection (logger, user)
- Domain models separate from database models
- Middleware for authentication and request handling
## Code Organization
### Project Structure
```
cmd/ # Application entry points
server/ # Main web server
cleanup-instances/ # Utility: cleanup instances
cleanup-tunnels/ # Utility: cleanup tunnels
internal/ # Internal application code
appctx/ # Context helpers
apperrs/ # Custom error types
cloudflare/ # Cloudflare API client
config/ # Configuration management
db/ # SQLC-generated database code
handler/ # HTTP handlers
components/ # Templ templates
static/ # Embedded static files
provisioning/ # Kubernetes provisioning
n8ntemplates/ # N8N deployment templates
services/ # Business logic
pkg/ # Reusable packages
migrations/ # SQL migrations
k8s/ # Kubernetes manifests
```
### Naming Conventions
- **Exported**: PascalCase (e.g., `CreateInstance`)
- **Unexported**: camelCase (e.g., `validateSubdomain`)
- **Packages**: lowercase, single word
- **Files**: lowercase with underscores (e.g., `instances_test.go`)
### Import Organization
Always organize imports in three groups:
```go
import (
// 1. Standard library
"context"
"fmt"
// 2. External dependencies
"github.com/samber/lo"
// 3. Internal packages
"github.com/aliuygur/n8n-saas-api/internal/db"
)
```
## Development Workflow
### Build Commands (via Makefile)
- `make build` - Build binary to bin/server
- `make run` - Build and run server
- `make dev` - Run with templ live reload (watches templates and proxies to port 8081)
- `make test` - Run tests
- `make clean` - Remove build artifacts
- `make sqlc` - Generate database code from SQL
- `make templ` - Generate Go code from templ templates
- `make fmt` - Format code
- `make lint` - Run golangci-lint
- `make tidy` - Clean up dependencies
- `make deps` - Install development dependencies (sqlc, templ)
- `make env` - Create .env from .env.example
- `make gcloud-build` - Build and submit Docker image to Google Cloud Build
### Code Generation
**IMPORTANT**: After modifying templates or SQL, run generators:
- Modified `.templ` files → Run `make templ`
- Modified `.sql` files → Run `make sqlc`
- Generated files ARE committed to git
### Testing
- Use standard `testing` package
- Test files: `*_test.go` alongside implementation
- Run tests with `make test`
## Coding Standards
### Error Handling
Use custom error package (`internal/apperrs`) with two kinds:
- `apperrs.Client` - Client errors (4xx) with error codes
- `apperrs.Server` - Server errors (5xx)
Error codes: `NotFound`, `InvalidInput`, `Unauthorized`, `Conflict`, `Forbidden`, etc.
Example:
```go
if subdomain == "" {
return apperrs.Client("subdomain is required", apperrs.InvalidInput)
}
if err := db.Query(ctx); err != nil {
return apperrs.Server("failed to query database", err)
}
```
### Logging
Use structured logging with `log/slog`:
- Attach logger to context via `appctx.Logger(ctx)`
- Log levels: Debug, Info, Error
- Include relevant context (user ID, instance ID, etc.)
Example:
```go
logger := appctx.Logger(ctx)
logger.Info("creating instance",
"subdomain", subdomain,
"user_id", userID,
)
```
### Authentication
Two middleware helpers:
- `requireAuth` - For pages (redirects to `/login`)
- `requireAuthAPI` - For API endpoints (returns 401 JSON)
Get current user from context:
```go
user := appctx.User(ctx)
```
### Database Queries
- Write SQL in `internal/db/queries/*.sql`
- Use SQLC annotations (`-- name: QueryName :one`, `:many`, `:exec`)
- Always handle `pgx.ErrNoRows` explicitly
- Use transactions for multi-step operations
- Use `FOR UPDATE` when row locking is needed
Example SQLC query:
```sql
-- name: GetInstanceBySubdomain :one
SELECT * FROM instances
WHERE subdomain = $1 AND deleted_at IS NULL
LIMIT 1;
```
### HTTP Handlers
- Use Go 1.22+ routing: `GET /path`, `POST /path/{id}`
- Return errors, don't panic
- Use templ for HTML rendering
- Use JSON for API responses
Example handler:
```go
func (h *Handler) handleCreateInstance(w http.ResponseWriter, r *http.Request) error {
var req CreateInstanceRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return apperrs.Client("invalid request body", apperrs.InvalidInput)
}
instance, err := h.svc.CreateInstance(r.Context(), req)
if err != nil {
return err
}
return writeJSON(w, http.StatusCreated, instance)
}
```
### Configuration
- Use environment variables via `.env` file
- Load config in `internal/config/config.go`
- Validate on startup
- Never hardcode secrets
## Kubernetes & Infrastructure
### Instance Provisioning
Each n8n instance gets:
- Dedicated Kubernetes namespace
- PersistentVolumeClaim (5Gi premium-rwo)
- Deployment with main container (n8nio/n8n:2.1.4) + sidecar (task runners)
- ClusterIP Service on port 80
- Cloudflare Tunnel route for ingress
Templates located in: `internal/provisioning/n8ntemplates/templates/`
### Cloudflare Integration
- Dynamic tunnel route creation
- Automatic DNS CNAME records
- Subdomain format: `{subdomain}.ranx.cloud`
- Tunnel ID and Account ID in config
### Security Best Practices
- Run containers as non-root (UID 65532)
- Read-only root filesystem
- Workload Identity for GCP access
- Environment variable isolation
- Blocked n8n nodes: `executeCommand`, `localFileTrigger`
## Domain-Specific Rules
### Instance Management
- Subdomains must be unique (enforced at DB level)
- Soft deletes (set `deleted_at` timestamp)
- Instance states: creating, running, failed, deleted
- Cleanup jobs run periodically via cron utilities
### Subdomain Validation
Use `pkg/domainutils` for validation:
- 3-63 characters
- Lowercase alphanumeric + hyphens
- Cannot start/end with hyphen
- No reserved words (www, api, admin, etc.)
### Routing
- Public routes: `/`, `/login`, `/pricing`, `/terms`, `/privacy`
- Authenticated pages: `/dashboard`, `/instances/{id}`, `/account`
- API endpoints: `/api/*`
- Static files: `/static/*` (embedded FS)
- Subdomain proxy: Custom 404 handler routes `{subdomain}.ranx.cloud` to n8n instances
## Testing & Quality
### Before Committing
- Run `make fmt` to format code
- Run `make lint` to check for issues
- Run `make test` to verify tests pass
- Run `make tidy` to clean dependencies
- Ensure generated code is up to date (`make templ`, `make sqlc`)
### Code Review Checklist
- [ ] Error handling uses `apperrs` package
- [ ] Logging includes relevant context
- [ ] SQL queries use SQLC (no raw SQL)
- [ ] Input validation for all user inputs
- [ ] Authentication checked on protected routes
- [ ] Transactions used for multi-step DB operations
- [ ] No secrets hardcoded
- [ ] Imports properly organized
## Deployment
### Docker
- Multi-stage build (golang:1.25-alpine → distroless)
- Binary built in builder stage
- Minimal final image for security
- Runs on port 8080
### Kubernetes
- Kustomize for environment overlays (base, prod, stage)
- Manifests in `k8s/app/`
- Secrets managed via Kubernetes Secrets
- Service account: instol-app-sa
### GCP
- Container registry: `us-central1-docker.pkg.dev`
- Build with: `make gcloud-build`
- Manual deployment currently (CI/CD planned)
## Anti-Patterns to Avoid
- Don't use raw SQL strings (use SQLC)
- Don't panic in handlers (return errors)
- Don't log sensitive data (passwords, tokens)
- Don't bypass authentication middleware
- Don't ignore context cancellation
- Don't use global state
- Don't commit secrets or `.env` files
- Don't modify generated code manually (regenerate instead)
## Useful Commands
```bash
# Development
make dev # Run with live reload (templ watch + proxy)
make run # Build and run server
make clean # Clean build artifacts
# Code generation
make templ # Generate from .templ files
make sqlc # Generate from .sql files
# Testing & Quality
make test # Run tests
make lint # Run linter
make fmt # Format code
make tidy # Tidy dependencies
# Setup
make deps # Install development dependencies
make env # Create .env from .env.example
# Build & Deploy
make build # Build binary to bin/server
make gcloud-build # Build Docker image on GCP with Cloud Build
```
## Environment Variables
Key environment variables (see `.env.example`):
- `PORT` - Server port (default: 8080)
- `DATABASE_URL` - PostgreSQL connection string
- `SESSION_SECRET` - Session encryption key
- `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` - OAuth credentials
- `CLOUDFLARE_TUNNEL_ID`, `CLOUDFLARE_ACCOUNT_ID` - Tunnel config
- `CLOUDFLARE_API_TOKEN` - Cloudflare API access
- `K8S_NAMESPACE` - Kubernetes namespace for instances
- `ENVIRONMENT` - `development`, `staging`, or `production`
## Additional Resources
- Business model: `APP.md`
- TODO items: `TODO.md`
- Copilot instructions: `.github/copilot-instructions.md`
- SQL schema: `migrations/001_init.up.sql`
- SQLC config: `sqlc.yaml`
- Templ docs: https://templ.guide
- SQLC docs: https://docs.sqlc.dev
## Notes
- Frontend uses HTMX patterns - avoid full page reloads
- All times stored in UTC in databaseCLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
by AgentHub Crawler
CLAUDE.md
Guidance for Claude Code when working in this repository.
by AgentHub Crawler
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
by AgentHub Crawler
AHKv2 Cline Rules System
This repo has the docs needed to create a useful Autohotkey v2 project in Claude.
Sign in to leave a comment.
by AgentHub Crawler