First off, thank you for considering contributing to NOCIQ! It's people like you that make NOCIQ such a great tool for network operations teams.
NOCIQ is part of the Stellar Wave Program! If you're here from the Wave:
- Browse Issues: Look for issues tagged with
Stellar Wave - Apply to Work: Comment on the issue you want to work on
- Get Assigned: Wait for a maintainer to assign you
- Submit PR: Create a pull request when ready
Important: Only one contributor per issue. First to apply and get assigned gets the work.
There are many ways to contribute to NOCIQ:
- Report bugs and issues
- Suggest new features or enhancements
- Fix bugs and implement features
- Improve documentation
- Write tests to increase coverage
- Review pull requests
- Help answer questions in discussions
For Frontend (noc-iq-fe):
- Node.js 18.x or higher
- npm or yarn
- Git
- Freighter wallet (for Stellar features)
For Backend (noc-iq-be):
- Python 3.9 or higher
- pip and virtualenv
- Git
For Smart Contracts (noc-iq-contracts):
- Rust and Cargo
- Soroban CLI
- Stellar CLI
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/noc-iq-fe.git # or git clone https://github.com/YOUR_USERNAME/noc-iq-be.git # or git clone https://github.com/YOUR_USERNAME/noc-iq-contracts.git
- Add upstream remote:
git remote add upstream https://github.com/OpSoll/noc-iq-fe.git
Frontend:
cd noc-iq-fe
npm install
cp .env.example .env.local
# Edit .env.local with your config
npm run devBackend:
cd noc-iq-be
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
# Edit .env with your config
uvicorn main:app --reloadSmart Contracts:
cd noc-iq-contracts
# Install Soroban CLI if you haven't
cargo install --locked soroban-cli
# Build contracts
make build
# Run tests
make testAlways create a new branch for your work:
git checkout -b feature/wallet-integration
# or
git checkout -b fix/payment-bug
# or
git checkout -b docs/stellar-guideBranch naming convention:
feature/description- New featuresfix/description- Bug fixesdocs/description- Documentationtest/description- Adding testsrefactor/description- Code refactoring
- Write clean, readable code
- Follow the project's code style (see below)
- Add tests for new functionality
- Update documentation as needed
- Keep commits focused and atomic
- Update
CHANGELOG.mdfor any interface-affecting changes (added/changed/removed public functions)
Frontend:
npm run test
npm run lint
npm run type-checkBackend:
pytest
pytest --cov=app --cov-report=html
black app/
flake8 app/
mypy app/Smart Contracts:
cargo test
cargo clippy -- -D warningsWe follow Conventional Commits:
git commit -m "feat: add wallet balance display"
git commit -m "fix: resolve payment timeout issue"
git commit -m "docs: update stellar integration guide"
git commit -m "test: add unit tests for SLA calculator"Commit message format:
<type>: <description>
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, semicolons, etc.)refactor: Code refactoringtest: Adding or updating testschore: Maintenance tasksperf: Performance improvements
git push origin feature/wallet-integrationThen open a pull request on GitHub with:
- Clear title following conventional commit format
- Description of what you changed and why
- Screenshots (for UI changes)
- Testing notes (how you tested the changes)
- Related issue:
Closes #123orFixes #456
- Use TypeScript for all new files
- Follow React hooks best practices
- Use functional components over class components
- Use Tailwind CSS for styling (no inline styles)
- Use shadcn/ui components when available
- Extract reusable logic into custom hooks
- PropTypes or TypeScript interfaces for all components
Example:
import { useState } from 'react';
import { Button } from '@/components/ui/button';
interface WalletConnectProps {
onConnect: (publicKey: string) => void;
}
export function WalletConnect({ onConnect }: WalletConnectProps) {
const [connected, setConnected] = useState(false);
// Component logic here
return (
<Button onClick={handleConnect}>
{connected ? 'Disconnect' : 'Connect Wallet'}
</Button>
);
}- Follow PEP 8 style guide
- Use type hints for all functions
- Write docstrings for all public functions
- Use async/await for I/O operations
- Pydantic models for request/response validation
- Dependency injection for services
- Environment variables for configuration
Example:
from fastapi import APIRouter, Depends, HTTPException
from app.models.payment import PaymentCreate, PaymentResponse
from app.services.stellar.payment_service import PaymentService
from app.api.deps import get_current_user
router = APIRouter()
@router.post("/payments", response_model=PaymentResponse)
async def create_payment(
payment: PaymentCreate,
current_user = Depends(get_current_user)
) -> PaymentResponse:
"""
Create a new payment transaction on Stellar network.
Args:
payment: Payment details including amount and destination
current_user: Currently authenticated user
Returns:
PaymentResponse with transaction hash and status
Raises:
HTTPException: If payment creation fails
"""
service = PaymentService()
result = await service.create_payment(payment)
return result- Follow Rust best practices
- Document all public functions
- Use proper error handling
- Test all functions thoroughly
- Keep gas costs in mind
- Use clippy for linting
Example:
#[contractimpl]
impl SLAContract {
/// Calculate SLA result for an outage
///
/// # Arguments
/// * `outage_id` - Unique identifier for the outage
/// * `severity` - Severity level (Critical, High, Medium, Low)
/// * `mttr_minutes` - Mean time to repair in minutes
///
/// # Returns
/// SLAResult containing status and payment information
pub fn calculate_sla(
env: Env,
outage_id: Symbol,
severity: Severity,
mttr_minutes: u32,
) -> SLAResult {
// Implementation here
}
}- Code follows the style guidelines
- Self-review completed
- Tests added/updated and passing
- Documentation updated
- No console.log or print statements
- Environment variables in .env.example
- Breaking changes clearly documented
## Description
Brief description of the changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Related Issue
Closes #123
## Testing
- [ ] Unit tests added/updated
- [ ] Integration tests added/updated
- [ ] Manual testing completed
## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Documentation updated
- [ ] Tests pass locally
## Screenshots (if applicable)
[Add screenshots here]
## Additional Notes
Any additional information for reviewersInclude in your PR description:
- Testnet transaction hashes (for blockchain features)
- Video/GIF of feature working (for UI changes)
- Performance metrics (if relevant)
- Time spent on the issue (optional)
# Run all tests
npm run test
# Run tests in watch mode
npm run test:watch
# Run with coverage
npm run test:coverageTest structure:
import { render, screen, fireEvent } from '@testing-library/react';
import { WalletConnect } from './WalletConnect';
describe('WalletConnect', () => {
it('should connect to Freighter wallet', async () => {
render(<WalletConnect onConnect={jest.fn()} />);
const button = screen.getByText('Connect Wallet');
fireEvent.click(button);
// Assertions here
});
});# Run all tests
pytest
# Run specific test file
pytest tests/test_payment_service.py
# Run with coverage
pytest --cov=app --cov-report=htmlTest structure:
import pytest
from app.services.stellar.payment_service import PaymentService
@pytest.mark.asyncio
async def test_create_payment():
"""Test payment creation on Stellar network"""
service = PaymentService(network="testnet")
result = await service.create_payment(
source_secret="S...",
destination="G...",
amount="10.00"
)
assert result["status"] == "success"
assert "tx_hash" in result# Run tests
cargo test
# Run with output
cargo test -- --nocapture- Use clear, concise language
- Include code examples
- Add screenshots for UI features
- Keep up-to-date with code changes
- Link to related docs where helpful
- Use Markdown for formatting
- Never commit secrets (API keys, private keys, passwords)
- Use environment variables for sensitive data
- Follow principle of least privilege
- Validate all inputs
- Use prepared statements for database queries
- Sanitize user inputs
- Keep dependencies updated
Use the GitHub issue template and include:
- Clear title describing the bug
- Steps to reproduce the issue
- Expected behavior
- Actual behavior
- Screenshots (if applicable)
- Environment details (OS, browser, versions)
- Error messages (full stack trace if possible)
- For Stellar issues: Include network (testnet/mainnet) and transaction hash
Use the GitHub issue template and include:
- Clear title describing the feature
- Problem statement (what problem does this solve?)
- Proposed solution
- Alternative solutions considered
- Additional context (mockups, examples, etc.)
- GitHub Issues: For bugs and feature requests
- Discord: [Join our server] (link TBD)
- Stellar Discord: For Stellar-specific questions
By contributing to NOCIQ, you agree that your contributions will be licensed under the MIT License.
Your contributions make NOCIQ better for everyone. We appreciate your time and effort!
Use this checklist when reviewing PRs that touch governance, config, or storage.
- All privileged functions call
require_auth()on the correct role (admin or operator) - No function bypasses the role check under any code path
- Role assignments (admin, operator) can only be changed by the current admin
- Pause/unpause state is checked at the top of every write function
-
set_configonly accepts valid severity symbols (critical / high / medium / low) -
threshold_minutes,penalty_per_minute, andreward_baseare validated as non-zero positive values - Config changes emit a versioned
cfg_updevent with the new values - After a config write the backend parity tests are re-run against the updated snapshot
- No new storage key is added without a corresponding version bump or migration path
- Persistent storage writes are minimised β avoid writes on read-only queries
- History pruning operations are admin-gated and emit a
prunedevent
- Contract-paused guard is present in all state-changing functions
- Pause state is correctly persisted and readable via
get_paused - Tests cover behaviour of every write function while paused
- New public functions are added to the result schema or documented if they are read-only helpers
- Any breaking change to
SLAResultincrementsRESULT_SCHEMA_VERSION - CI passes:
cargo fmt --check,cargo clippy -- -D warnings,cargo test,wasm32build
Happy coding! π