Development Guide¶
This guide covers the development workflow for ocmonica.
Prerequisites¶
- Go: 1.25.2 or later
- Node.js: 20 or later
- Task: Task runner (installation)
- Buf: For protobuf generation (installation)
- golangci-lint: For Go linting (installation)
Quick Start¶
Initial Setup¶
# Install dependencies and initialize config
task setup
# Or manually:
task install # Install Go dependencies
task web:install # Install Node.js dependencies
task config:init # Create config files from examples
Development Mode¶
Run both backend and frontend together:
This will start: - Backend server on http://localhost:8080 - Frontend dev server on http://localhost:3000
Press Ctrl+C to stop both servers.
Run Servers Separately¶
Backend only:
Frontend only:
Hot Reload Development¶
Ocmonica supports hot reload for both backend and frontend during development, allowing you to see changes instantly without manual rebuilds.
Quick Start¶
# Local development with full hot reload (recommended)
task dev:watch:full
# Or Docker with observability stack
task docker:dev
Local Development (Recommended for Daily Work)¶
Backend Hot Reload with Air¶
Air watches your Go files and automatically rebuilds/restarts the server when changes are detected.
Install (included in task setup):
Run:
What Gets Watched:
- All .go files in cmd/, internal/, pkg/
- Configuration files: .toml, .yaml
Rebuild Time: ~2-3 seconds for typical changes
Build Output: Compiled to tmp/main (gitignored)
Configuration: .air.toml in project root
Frontend Hot Reload with Next.js¶
Next.js has hot reload built-in with Turbopack enabled by default.
# Frontend only
task web:dev
# Or use dev:watch:full for both backend and frontend
task dev:watch:full
What Gets Watched: All files in web/src/
Reload Time: < 1 second (hot module replacement)
No configuration needed: Works out of the box
Docker Development (For Full Stack Testing)¶
Run the complete development stack in Docker with hot reload enabled:
# Start all services (foreground)
task docker:dev
# Or start in background
task docker:dev:up
# View logs
task docker:dev:logs
# View specific service logs
task docker:dev:logs:backend
task docker:dev:logs:frontend
# Stop containers
task docker:dev:down
# Clean up (stop + remove volumes)
task docker:dev:clean
Services Started: - Backend (Go + Air): http://localhost:8080 - Frontend (Next.js): http://localhost:3000 - Jaeger UI: http://localhost:16686 - Prometheus: http://localhost:9091 - Grafana: http://localhost:3001 (admin/admin)
How It Works: - Source code is mounted as Docker volumes - Air watches Go files and rebuilds in container - Next.js watches TypeScript/React files with polling - Changes on host → automatically reflected in container
Troubleshooting¶
Backend not rebuilding¶
Symptoms: Code changes don't trigger rebuild
Solutions:
- Check Air is running (you should see colored output)
- Verify .air.toml exists in project root
- Check tmp/ directory is created and writable
- Look for errors in build-errors.log
- Ensure file is in a watched directory (cmd/, internal/, pkg/)
Frontend not hot reloading in Docker¶
Symptoms: Changes to TypeScript/React files not reflected in browser
Solutions:
- Verify WATCHPACK_POLLING=true in docker-compose environment
- Check browser console for errors
- Ensure node_modules is excluded from volume mount (check docker-compose.dev.yml)
- Hard refresh browser: Cmd+Shift+R (Mac) / Ctrl+Shift+R (Windows/Linux)
- Restart frontend container: docker-compose -f docker-compose.dev.yml restart frontend
Slow rebuilds¶
Symptoms: Air takes > 5 seconds to rebuild
Possible causes: - Large codebase (expected for first build) - Too many files changing at once - Disk I/O bottleneck
Solutions:
- First build is always slower (go mod download, etc.)
- Subsequent builds should be fast (< 3 seconds)
- Adjust delay in .air.toml if builds trigger too frequently (default: 1000ms)
- For Docker on Mac/Windows, file watching can be slower due to virtualization
- Consider using local development (task dev:watch:full) for faster iteration
Port conflicts¶
Symptoms: Error "port already in use" or "address already in use"
Check what's using a port:
Solutions: - Stop other services using those ports - Or modify ports in docker-compose.dev.yml
Docker volume permission issues¶
Symptoms: Permission denied errors in container logs
Solutions:
- Ensure your user has write permissions to project directory
- On Linux, you may need to adjust the container user (currently using root in dev Dockerfile)
- Check Docker Desktop settings (Mac/Windows)
Debugging with Chrome DevTools¶
Both local and Docker development setups support Node.js debugging via Chrome DevTools for the Next.js frontend. This allows you to debug server-side code including Server Components, API routes, and middleware.
Enable Debugging¶
Debugging is enabled by default:
- Local: npm run dev from web/ directory
- Docker: task docker:dev from project root
- Port 9229 exposed for debugger connection
Attach Chrome DevTools¶
- Navigate to
chrome://inspectin Chrome - Click "Configure..." and ensure
localhost:9229is in the list - Under "Remote Target", click "inspect" for the Node.js process
- DevTools window opens with full debugging capabilities
Debugging Features¶
Set Breakpoints: Click line numbers in Sources tab to set breakpoints
Inspect Variables: Hover over variables to see values
Call Stack: View the full call stack when paused
Console: Use console.log() - output appears in DevTools console
Performance: Profile server-side rendering performance
Hot Reload: Debugger persists through hot-reload cycles
What Can You Debug?¶
✅ Server Components (default in app/ directory)
✅ API Routes (app/api/ directory)
✅ Middleware (middleware.ts)
✅ Server Actions
✅ Data fetching in Server Components
❌ Client Components ('use client' directive) - use browser DevTools instead
❌ Browser event handlers - use browser DevTools
Debugging Ports¶
- 3000 - Next.js dev server
- 9229 - Node.js debugger (Chrome DevTools)
Troubleshooting¶
Connection refused:
- Ensure dev server is running
- Verify port 9229 is not blocked by firewall
- Check chrome://inspect has localhost:9229 configured
Breakpoints not hitting: - Verify you're debugging server code, not client components - Check Source Maps are enabled in DevTools settings - Ensure file path in DevTools matches your filesystem
Port conflict (9229 in use):
- Stop other Node.js debuggers
- Check with: lsof -i :9229 (Mac/Linux)
- Kill process: lsof -ti :9229 | xargs kill -9
Docker connection issues:
- Verify port mapping: docker port ocmonica-frontend-dev
- Check docker-compose.dev.yml has port 9229:9229 mapped
- Restart frontend container if needed
See web/CLAUDE.md for detailed debugging guide.
When to Use Which Approach¶
| Scenario | Recommended Command | Why |
|---|---|---|
| Daily backend development | task dev:watch |
Fastest iteration, minimal overhead |
| Daily full-stack development | task dev:watch:full |
Both services with hot reload locally |
| Testing with observability | task docker:dev |
Full stack with Jaeger/Prometheus/Grafana |
| Quick frontend changes | task web:dev |
Frontend only, no backend needed |
| Testing production build | task build-all |
Verify production configuration |
| CI/CD pipeline | Production builds | No hot reload needed |
Performance Tips¶
- Use local development for fastest iteration: Docker adds overhead for file watching
- Keep changes focused: Editing many files at once can slow down rebuilds
- Use
.air.tomldelay setting: 1 second default prevents rebuilding on every keystroke - Exclude unnecessary directories: Check
.air.tomlexcludes (vendor, gen, etc.) - On Mac/Windows: Consider increasing Docker resources (CPU/memory) for better performance
Project Structure¶
ocmonica/
├── cmd/server/ # Backend entry point
├── internal/ # Private application code
│ ├── api/ # API handlers (REST & gRPC)
│ ├── service/ # Business logic
│ ├── repository/ # Data access
│ └── models/ # Domain models
├── pkg/ # Public libraries
│ ├── config/ # Configuration management
│ └── utils/ # Utility functions
├── proto/ # Protobuf definitions
├── gen/ # Generated Go code (gitignored)
├── web/ # TypeScript frontend
│ ├── src/
│ │ ├── app/ # Next.js pages
│ │ ├── components/ # React components
│ │ ├── lib/ # Utilities and API clients
│ │ ├── types/ # TypeScript types
│ │ └── gen/ # Generated TS code (gitignored)
│ └── public/ # Static assets
├── Taskfile.yaml # Task definitions
└── README.md
Common Development Tasks¶
Building¶
# Build backend binary
task build
# Build frontend for production
task web:build
# Build everything
task build-all
Testing¶
# Run all Go tests
task test
# Run tests with coverage report
task test:coverage
# Test specific layers
task service:test
task db:test
task config:test
Code Quality¶
# Run all CI checks (format, lint, test, security, build)
task ci
# Run all quality checks (lint, test, security)
task quality:all
# Format Go code
task fmt
# Lint Go code
task lint
# Auto-fix linting issues
task lint:fix
# Lint frontend code
task web:lint
Security Scanning¶
The project uses gosec for Go security analysis and Trivy for dependency vulnerability scanning.
Installation¶
Running Security Scans¶
# Quick security scan (console output)
task security:scan
# Generate detailed security reports (JSON, HTML, text)
task security:report
# Generate SARIF report for GitHub Code Scanning
task security:sarif
# Run comprehensive quality report (includes security scan)
task quality:report
Understanding Security Findings¶
gosec Rule IDs: - G103: Use of unsafe calls (low severity) - Common in generated protobuf code - G115: Integer overflow conversion (high severity) - Check int to int32 conversions - G201: SQL string formatting (medium severity) - Potential SQL injection - G301: File/directory permissions (medium severity) - Expect 0750 or less - G304: Path traversal (medium severity) - Variable file paths
Severity Levels: - HIGH: Address immediately - potential security vulnerability - MEDIUM: Review and fix - may pose security risk - LOW: Informational - audit but may be acceptable
CI/CD Integration¶
Security scans run automatically on every push and pull request via GitHub Actions:
- gosec - Scans Go code for security issues
- Trivy - Scans for dependency vulnerabilities
Results are uploaded to GitHub Security tab (Code Scanning Alerts).
Excluding False Positives¶
If gosec reports a false positive that's been validated as safe:
IMPORTANT: Always include a comment explaining WHY the finding is safe. Never suppress without justification.
Security Report Location¶
Reports are generated in ./reports/ directory:
- gosec-report.json - Machine-readable JSON format
- gosec-report.html - Human-readable HTML report
- gosec-report.txt - Console-friendly text format
- gosec.sarif - SARIF format for GitHub integration
The reports/ directory is gitignored.
Git Hooks¶
Overview¶
ocmonica uses Lefthook for git hooks to automatically: - Format code before commit - Run linters on changed files - Validate protobuf files - Enforce commit message format (conventional commits) - Maintain code quality standards
Hooks are fast (typically < 5 seconds) and run in parallel.
Installation¶
Hooks are installed automatically during task setup. To install manually:
# Install Lefthook binary
go install github.com/evilmartians/lefthook@latest
# Install hooks into .git/hooks/
lefthook install
Configuration¶
Hooks are configured in lefthook.yml at project root.
Key configuration highlights:
- Parallel execution for speed
- File filtering via glob patterns (only run on relevant files)
- Auto-fixing with stage_fixed: true (auto-stage fixed files)
- Skip conditions for merge/rebase operations
- Minimal output (only shows errors, not successes)
What Runs When?¶
On git commit (pre-commit hook):
| Check | Files | Command | Auto-fix |
|---|---|---|---|
| Go imports | *.go |
goimports -w |
✅ Yes |
| Go format | *.go |
go fmt |
✅ Yes |
| Go lint (fast) | *.go |
golangci-lint --fast |
❌ No |
| Protobuf lint | proto/**/*.proto |
buf lint |
❌ No |
| Protobuf format | proto/**/*.proto |
buf format -w |
✅ Yes |
| TypeScript lint | web/**/*.{ts,tsx,js,jsx} |
npm run lint |
⚠️ Partial |
| Commit message | All commits | Conventional commits check | ❌ No |
Generated code excluded: Files in gen/ directory are automatically skipped.
On git push (pre-push hook):
| Check | Command | Purpose |
|---|---|---|
| Full Go lint | golangci-lint run |
All linters (not just fast) |
| Go tests | go test -short -race ./... |
Run test suite |
| Security scan | gosec ./... |
Security vulnerability check |
| Frontend build | npm run build |
Ensure TypeScript compiles |
All checks run only on staged files for pre-commit, and all files for pre-push.
Running Hooks Manually¶
# Run pre-commit checks on staged files
task hooks:run
# Or directly with Lefthook
lefthook run pre-commit
# Run on all files (not just staged)
lefthook run pre-commit --all-files
# Run pre-push checks
lefthook run pre-push
# Run specific hook
lefthook run go-lint-fast
Skipping Hooks¶
When to Skip: - Emergency hotfixes - WIP commits on feature branch - Experimenting with code - When you know the hook will fail and want to fix it later
How to Skip:
# Method 1: Git flag (works with any hook tool)
git commit --no-verify -m "WIP: work in progress"
# Method 2: Lefthook env var (skip all hooks)
LEFTHOOK=0 git commit -m "skip all hooks"
# Method 3: Skip specific hook
LEFTHOOK_EXCLUDE=go-lint-fast git commit -m "skip just linting"
# Method 4: Skip on merge/rebase (automatic)
# Some hooks automatically skip during merge/rebase
⚠️ Important:
- Never skip hooks on commits to main branch
- CI will catch issues, but hooks prevent bad code from being pushed
- Use --no-verify sparingly - it's a last resort
Commit Message Format¶
Hooks enforce Conventional Commits format:
Format: <type>(<scope>): <description>
Examples:
git commit -m "feat(auth): add JWT token refresh"
git commit -m "fix(api): resolve null pointer in file handler"
git commit -m "docs: update README with installation steps"
git commit -m "refactor(service): extract user validation logic"
git commit -m "test(repository): add tests for file CRUD operations"
Valid types:
- feat - New feature
- fix - Bug fix
- docs - Documentation changes
- style - Code style changes (formatting, missing semicolons, etc.)
- refactor - Code refactoring (no functionality change)
- test - Adding or updating tests
- chore - Maintenance tasks (dependencies, build, etc.)
- perf - Performance improvements
- ci - CI/CD changes
- build - Build system changes
- revert - Revert a previous commit
Scope is optional but recommended:
- auth - Authentication/authorization
- api - API handlers
- service - Service layer
- repository - Data access layer
- config - Configuration
- web - Frontend
Troubleshooting¶
Hooks not running:
# Reinstall hooks
lefthook install
# Check if hooks are installed
ls -la .git/hooks/pre-commit
# Should show a symlink or script
Slow commits:
# See which hook is slow (verbose mode)
lefthook run pre-commit -v
# If a specific hook is slow, skip it
LEFTHOOK_EXCLUDE=go-security git commit -m "WIP"
# Or move slow checks to pre-push in lefthook.yml
Hook fails on valid code:
# Run hook manually to debug
lefthook run pre-commit -v
# Run the specific tool that's failing
golangci-lint run --fast ./...
buf lint
npm run lint
# Check if file is excluded
# (Generated files in gen/ should be excluded)
Conventional commit validation fails:
# Your commit message must match the format
# Bad: "updated code"
# Good: "feat: add new feature"
# Fix by amending your commit message
git commit --amend -m "feat(api): add user registration endpoint"
Disable hooks permanently (not recommended):
Node.js not found in pre-commit:
# Ensure Node.js is in your PATH
which node
which npm
# If not, add to your shell profile (~/.bashrc, ~/.zshrc)
export PATH="/usr/local/bin:$PATH"
Go tools not found:
# Install required Go tools
task setup
# Or manually
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
Available Tasks¶
task hooks:install # Install git hooks
task hooks:run # Run pre-commit hooks manually
task hooks:run-all # Run pre-commit hooks on all files
task hooks:uninstall # Remove git hooks
CI/CD Integration¶
The same hooks run in GitHub Actions CI. See .github/workflows/ci.yml and .github/workflows/lint.yml.
Benefits: - Consistent checks locally and in CI - Faster PR reviews (code is pre-linted) - Fewer CI failures (issues caught before push)
Performance Tips¶
1. Only lint changed files (already configured)
- Pre-commit runs on {staged_files} only
- Full checks run in pre-push and CI
2. Use --fast mode for pre-commit (already configured)
- Fast linters only (< 1 second)
- Full linting in pre-push and CI
3. Skip slow checks for WIP commits
4. Parallel execution (already enabled) - All hooks run concurrently - Typically completes in < 5 seconds
Customizing Hooks¶
To modify hook behavior, edit lefthook.yml:
# Example: Add a new pre-commit check
pre-commit:
commands:
my-custom-check:
glob: "*.go"
run: ./scripts/my-check.sh {staged_files}
# Example: Skip hook on specific branches
pre-commit:
commands:
go-lint-fast:
skip:
- ref: experimental/*
# Example: Add environment variables
pre-commit:
commands:
test:
run: go test ./...
env:
GO_TEST_VERBOSE: "1"
See Lefthook documentation for advanced configuration.
Developer Onboarding¶
New team members:
1. Clone repository
2. Run task setup (installs hooks automatically)
3. Make a test commit to verify hooks work
4. Read this documentation
If hooks are too strict:
- Use --no-verify for WIP commits on feature branches
- Never use --no-verify for commits to main
- CI will still catch issues even if hooks are skipped
Protobuf¶
# Generate Go code from protobuf
task proto:gen
# Generate TypeScript code for frontend
task web:gen
# Lint protobuf files
task proto:lint
# Format protobuf files
task proto:format
# Check for breaking changes
task proto:breaking
Database¶
Docker¶
# Build Docker image
task docker:build
# Build and run locally
task docker:run
# Build with git tag
task docker:build:tagged
# Push to registry
task docker:push
Development Workflow¶
1. Make Changes¶
Edit code in internal/, cmd/, web/src/, or proto/.
2. Generate Code (if needed)¶
After modifying protobuf files:
3. Run Tests¶
4. Check Code Quality¶
5. Commit Changes¶
Follow conventional commits:
git add .
git commit -m "feat: add new feature"
git commit -m "fix: resolve bug"
git commit -m "docs: update documentation"
6. Push and Create PR¶
API Endpoints¶
Authentication Endpoints¶
User Authentication:
- POST /api/v1/auth/register - Register new user
- POST /api/v1/auth/login - Login with username/password
- POST /api/v1/auth/refresh - Refresh access token
- POST /api/v1/auth/logout - Logout (revoke refresh token)
- POST /api/v1/auth/logout-all - Logout from all devices
- POST /api/v1/auth/change-password - Change user password
API Key Management:
- POST /api/v1/auth/api-keys - Create API key
- GET /api/v1/auth/api-keys - List user's API keys
- GET /api/v1/auth/api-keys/:id - Get API key details
- DELETE /api/v1/auth/api-keys/:id - Revoke API key
User Management:
- GET /api/v1/users/me - Get current user profile
- GET /api/v1/users/:id - Get user by ID (admin only)
File Management Endpoints (Authenticated)¶
GET /health- Health checkGET /api/v1/files- List filesPOST /api/v1/files- Upload fileGET /api/v1/files/:id- Get file metadataGET /api/v1/files/:id/download- Download fileDELETE /api/v1/files/:id- Delete filePOST /api/v1/directories- Create directoryGET /api/v1/directories/:id- Get directoryGET /api/v1/directories/:id/children- List directory childrenGET /api/v1/directories/:id/tree- Get directory treeDELETE /api/v1/directories/:id- Delete directoryGET /api/v1/search- Search files
gRPC API (Backend: :8080)¶
ConnectRPC services available at:
- /ocmonica.v1.FileService/* - File operations
- /ocmonica.v1.DirectoryService/* - Directory operations
- /ocmonica.v1.SearchService/* - Search operations
- /ocmonica.v1.AuthService/* - Authentication (planned)
Observability Endpoints¶
GET /metrics- Prometheus metrics endpoint- OpenTelemetry traces exported to configured OTLP endpoint
Frontend (Dev: :3000, Prod: :3000)¶
/- File browser interface (planned)
Configuration¶
Configuration is managed through environment variables and YAML files using Koanf v2.
Development Configuration¶
Create a config.yaml file (see README for full config):
server:
host: 0.0.0.0
port: 8080
read_timeout: 30s
write_timeout: 30s
database:
path: ./data/ocmonica.db
storage:
base_path: ./data/files
max_upload_size: 104857600 # 100MB
auth:
jwt:
access_token_duration: 15m
refresh_token_duration: 7d
rsa_key_size: 4096
password:
min_length: 12
require_upper: true
require_lower: true
require_number: true
require_symbol: true
registration:
enabled: true
default_role: "member"
api_key:
enabled: true
max_keys_per_user: 10
observability:
tracing:
enabled: true
endpoint: "http://localhost:4318" # Jaeger OTLP endpoint
metrics:
enabled: true
port: 9090
logging:
level: debug
format: json
Environment Variables¶
Override configuration with environment variables:
export SERVER_PORT=8080
export DATABASE_PATH=./data/ocmonica.db
export JWT_ACCESS_TOKEN_DURATION=15m
export REGISTRATION_ENABLED=true
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
Observability¶
OpenTelemetry Tracing (Jaeger)¶
Setup Jaeger locally:
# Run Jaeger all-in-one (Docker)
docker run -d --name jaeger \
-e COLLECTOR_OTLP_ENABLED=true \
-p 16686:16686 \
-p 4318:4318 \
jaegertracing/all-in-one:latest
# Access Jaeger UI
open http://localhost:16686
Enable tracing in config:
All requests are automatically traced with: - Request/response spans - Database operation spans - Service method spans - Error tracking - Custom attributes (user_id, organization_id, file_id, etc.)
Prometheus Metrics¶
Access metrics endpoint:
Available metrics:
- ocmonica_file_uploads_total - File upload counter
- ocmonica_file_downloads_total - File download counter
- ocmonica_auth_attempts_total - Authentication attempts
- ocmonica_db_query_duration_seconds - Database query latency
- ocmonica_search_queries_total - Search query counter
- ocmonica_active_users - Active user gauge
Setup Prometheus locally:
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'ocmonica'
static_configs:
- targets: ['localhost:9090']
# Run Prometheus
docker run -d --name prometheus \
-p 9091:9090 \
-v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
Grafana Dashboard (Optional)¶
# Run Grafana
docker run -d --name grafana \
-p 3001:3000 \
grafana/grafana
# Access at http://localhost:3001
# Default: admin/admin
Add Prometheus as datasource:
- URL: http://localhost:9091
- Access: Browser
Debugging¶
Backend Logs¶
Backend uses structured JSON logging:
Log fields:
- timestamp - ISO 8601 timestamp
- level - Log level (debug, info, warn, error)
- msg - Log message
- trace_id - OpenTelemetry trace ID
- span_id - OpenTelemetry span ID
- Additional context fields (user_id, file_id, etc.)
Distributed Tracing¶
View request flow in Jaeger UI:
1. Go to http://localhost:16686
2. Select service: ocmonica
3. Search for traces
4. Click trace to see detailed span breakdown
Frontend Dev Tools¶
Next.js provides hot reload and detailed error messages in development mode.
Database Inspection¶
SQLite database is at ./data/ocmonica.db:
sqlite3 ./data/ocmonica.db
.tables
SELECT * FROM files;
SELECT * FROM users;
SELECT * FROM organizations;
Troubleshooting¶
Port Already in Use¶
# Kill process on port 8080
lsof -ti:8080 | xargs kill -9
# Kill process on port 3000
lsof -ti:3000 | xargs kill -9
Dependencies Out of Sync¶
# Backend
go mod tidy
task install
# Frontend
cd web && rm -rf node_modules package-lock.json
npm install
Generated Code Issues¶
Clean Build¶
IDE Setup¶
VS Code¶
Recommended extensions: - Go (golang.go) - ESLint (dbaeumer.vscode-eslint) - Tailwind CSS IntelliSense (bradlc.vscode-tailwindcss) - Buf (bufbuild.vscode-buf)
GoLand / WebStorm¶
- Enable Go modules support
- Configure Node.js interpreter
- Enable ESLint and Prettier
Testing Strategy¶
Backend Tests¶
Test Status: ✅ All tests passing (9/9 packages)
Test Types: - Integration Tests: Full middleware stack with in-memory SQLite - Unit Tests: Service layer business logic with mocked dependencies - Repository Tests: Data access layer with real database operations - Handler Tests: REST and gRPC handlers with authentication
Test Packages:
go test ./...
# All passing:
# ✅ internal/api/grpc
# ✅ internal/api/rest/handlers
# ✅ internal/repository/sqlite
# ✅ internal/service
# ✅ internal/observability/metrics
# ✅ test (integration tests)
Running Tests:
# Run all tests
task test
# Run with coverage
task test:coverage
# Run specific package
go test ./internal/service/...
# Run with race detection
go test -race ./...
# Verbose output
go test -v ./...
Test Setup Pattern: All test files use a common pattern with metrics initialization and in-memory database:
func setupTestHandler(t *testing.T) (*Handler, func()) {
t.Helper()
// Initialize metrics (safe for concurrent tests)
metrics.Init("ocmonica-test")
// Create in-memory database
db, err := sql.Open("sqlite", ":memory:")
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
// Run migrations
if err := sqlite.RunMigrations(db); err != nil {
t.Fatalf("Failed to run migrations: %v", err)
}
// Setup repositories and services...
cleanup := func() {
_ = db.Close()
}
return handler, cleanup
}
Coverage Areas: - ✅ Authentication (register, login, logout, password change) - ✅ API Key management (create, list, revoke) - ✅ Permission checks (RBAC enforcement) - ✅ File operations (upload, download, delete) - ✅ Directory operations (create, list, tree) - ✅ Search functionality - ✅ Multi-tenancy isolation - ✅ Token refresh and validation
Integration Tests¶
Located in test/ directory:
- grpc_auth_integration_test.go - gRPC authentication flow
- rbac_integration_test.go - RBAC permission enforcement
Frontend¶
Currently planned. Future: Vitest/Jest for component tests.
Contributing¶
- Create a feature branch from
main - Make your changes following the guidelines above
- Ensure all tests pass:
task ci - Create a pull request
- Wait for CI checks to pass
- Request review