Development Guide
Guide for developers contributing to VulnerabilityHub.
Development Setup
Prerequisites
Python 3.9+
Node.js 16+ and npm
Docker and Docker Compose
Git
MySQL/MariaDB client tools
Local Development Environment
1. Clone and Setup
git clone <repository-url>
cd vulnerability-scanner
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install backend dependencies
cd backend
pip install -r requirements.txt
pip install -r requirements-dev.txt # Development dependencies
# Install frontend dependencies
cd ../frontend/app
npm install
2. Database Setup
# Start database only
docker-compose up -d db
# Initialize schema (password is in secrets/db_root_password.txt)
mariadb -h 127.0.0.1 -P 3306 -u root -p$(cat secrets/db_root_password.txt) vulnerabilityhub < src/database/vulnerability_scanner.sql
3. Environment Configuration
Create backend/.env:
ENV=development
SECRET_KEY=dev-secret-key
SMTP_SERVER=localhost
SMTP_PORT=1025
SMTP_SENDER=VulnerabilityHub <noreply@localhost>
BACKEND_URL=http://localhost:8000
# Database (defaults are usually fine for local docker db)
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=appuser
DB_PASSWORD=appuser_password_from_secret
Note
Ensure DB_PASSWORD matches secrets/db_password.txt.
4. Run Development Servers
Backend: .. code-block:: bash
cd backend uvicorn main:app –reload –host 0.0.0.0 –port 8000
Frontend:
cd frontend/app
npm run dev
Access: - Frontend: http://localhost:5173 (Vite dev server) - Backend API: http://localhost:8000 - API Docs: http://localhost:8000/docs
Project Structure
vulnerability-scanner/
├── backend/ # Python FastAPI backend
│ ├── core/ # Core utilities (DB, config, email)
│ ├── crud/ # Database operations
│ ├── models/ # SQLAlchemy models
│ ├── routes/ # API endpoints
│ ├── schemas/ # Pydantic schemas
│ ├── services/ # Business logic
│ ├── importers/ # Pluggable import system
│ ├── main.py # Application entry point
│ └── requirements.txt # Python dependencies
├── frontend/app/ # Vue 3 frontend
│ ├── src/
│ │ ├── components/ # Vue components
│ │ ├── views/ # Page components
│ │ ├── stores/ # Pinia stores
│ │ ├── router.ts # Vue Router config
│ │ └── main.ts # App entry point
│ ├── package.json # Node dependencies
│ └── vite.config.ts # Vite configuration
├── database/ # SQL schemas
├── grafana/ # Grafana dashboards
├── docs/ # Documentation
└── docker-compose.yml # Docker services
Backend Development
Adding a New API Endpoint
Create Route (
backend/routes/my_feature.py):
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from core.db import get_db
from routes.auth import get_current_admin_user
router = APIRouter()
@router.get("/my-feature")
def get_my_feature(
db: Session = Depends(get_db),
current_user = Depends(get_current_admin_user)
):
return {"message": "Hello from my feature"}
Register Router (
backend/main.py):
from routes import my_feature
app.include_router(my_feature.router)
Test:
curl http://localhost:8000/my-feature \
-H "Authorization: Bearer $TOKEN"
Adding a Database Model
Create Model (
backend/models/my_model.py):
from sqlalchemy import Column, Integer, String
from core.db import Base
class MyModel(Base):
__tablename__ = "my_table"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(255), nullable=False)
Create Schema (
backend/schemas/my_model.py):
from pydantic import BaseModel
class MyModelBase(BaseModel):
name: str
class MyModelCreate(MyModelBase):
pass
class MyModel(MyModelBase):
id: int
class Config:
from_attributes = True
Create CRUD (
backend/crud/my_model.py):
from sqlalchemy.orm import Session
from models.my_model import MyModel
from schemas.my_model import MyModelCreate
def create_my_model(db: Session, data: MyModelCreate):
db_obj = MyModel(**data.dict())
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
Update Database:
-- Add to database/vulnerability_scanner.sql
CREATE TABLE IF NOT EXISTS my_table (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL
);
Testing
Unit Tests
cd backend
pytest tests/
Integration Tests
pytest tests/integration/
Test Coverage
pytest --cov=. --cov-report=html
Frontend Development
Adding a New Component
Create Component (
frontend/app/src/components/MyComponent.vue):
<template>
<v-card>
<v-card-title>{{ title }}</v-card-title>
<v-card-text>
<p>{{ message }}</p>
</v-card-text>
</v-card>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const title = ref('My Component');
const message = ref('Hello from my component!');
</script>
<style scoped>
/* Component-specific styles */
</style>
Use Component:
<template>
<MyComponent />
</template>
<script setup>
import MyComponent from '@/components/MyComponent.vue';
</script>
Adding a New Route
Create View (
frontend/app/src/views/MyView.vue)Register Route (
frontend/app/src/router.ts):
{
path: '/my-view',
component: () => import('./views/MyView.vue'),
meta: { requiresAuth: true }
}
State Management with Pinia
Create Store (
frontend/app/src/stores/myStore.ts):
import { defineStore } from 'pinia';
import axios from 'axios';
export const useMyStore = defineStore('myStore', {
state: () => ({
items: [] as any[],
loading: false
}),
actions: {
async fetchItems() {
this.loading = true;
try {
const response = await axios.get('/api/items');
this.items = response.data;
} finally {
this.loading = false;
}
}
}
});
Use Store:
<script setup>
import { useMyStore } from '@/stores/myStore';
const store = useMyStore();
store.fetchItems();
</script>
Code Style Guidelines
Python (Backend)
Follow PEP 8
Use type hints
Maximum line length: 100 characters
Use docstrings for functions and classes
def process_scan(
db: Session,
scan_id: int,
options: Optional[Dict[str, Any]] = None
) -> Scan:
"""
Process a vulnerability scan.
Args:
db: Database session
scan_id: ID of scan to process
options: Optional processing options
Returns:
Processed scan object
"""
# Implementation
pass
TypeScript/Vue (Frontend)
Use TypeScript for type safety
Composition API for Vue components
Use
<script setup>syntaxComponent names in PascalCase
interface User {
id: number;
username: string;
isAdmin: boolean;
}
const fetchUser = async (id: number): Promise<User> => {
const response = await axios.get(`/users/${id}`);
return response.data;
};
SQL
Uppercase keywords
Descriptive table and column names
Always use indexes for foreign keys
CREATE TABLE IF NOT EXISTS my_table (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE INDEX idx_my_table_user ON my_table(user_id);
Git Workflow
Branch Naming
feature/description- New featuresbugfix/description- Bug fixeshotfix/description- Critical fixesrefactor/description- Code refactoring
Commit Messages
Follow conventional commits:
type(scope): description
[optional body]
[optional footer]
Types: feat, fix, docs, style, refactor, test, chore
Examples:
feat(predictions): add Prophet-based forecasting
fix(reports): correct 24-hour retention logic
docs(api): update endpoint documentation
Pull Request Process
Create feature branch from
mainMake changes and commit
Write/update tests
Update documentation
Create pull request
Request review
Address feedback
Merge after approval
Debugging
Backend Debugging
Using Python Debugger:
import pdb; pdb.set_trace() # Set breakpoint
VS Code launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "FastAPI",
"type": "python",
"request": "launch",
"module": "uvicorn",
"args": ["main:app", "--reload"],
"cwd": "${workspaceFolder}/backend"
}
]
}
Frontend Debugging
Browser DevTools: - Vue DevTools extension - Network tab for API calls - Console for errors
VS Code Debugging:
{
"type": "chrome",
"request": "launch",
"name": "Vue: Chrome",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}/frontend/app/src"
}
Database Migrations
Manual Migration
Update
database/vulnerability_scanner.sqlCreate migration script:
-- migrations/001_add_my_feature.sql
ALTER TABLE my_table ADD COLUMN new_field VARCHAR(255);
Apply migration:
mariadb -u root -p vulnerabilityhub < migrations/001_add_my_feature.sql
Future: Alembic Integration
Consider adding Alembic for automated migrations:
pip install alembic
alembic init alembic
alembic revision --autogenerate -m "Add my feature"
alembic upgrade head
Performance Optimization
Backend
Use database indexes
Implement caching (Redis)
Async operations where possible
Batch database operations
Frontend
Lazy load components
Virtual scrolling for large lists
Debounce user inputs
Code splitting
Database
Optimize queries (EXPLAIN)
Use materialized views (if available plugins) or summary tables
Regular OPTIMIZE TABLE / ANALYZE TABLE
Connection pooling
Contributing
Fork the repository
Create feature branch
Make changes
Add tests
Update documentation
Submit pull request