Knowledge Hub.
Comprehensive guides and references for the OpenFrame platform
Comprehensive guides and references for the OpenFrame platform
Welcome to OpenFrame! We appreciate your interest in contributing to our AI-powered MSP platform. This guide outlines our development workflow, code standards, and contribution process.
Before contributing, ensure you have:
Clone the repository:
git clone https://github.com/flamingo-stack/openframe-oss-tenant.git
cd openframe-oss-tenant
Start development dependencies:
./scripts/dev-start-dependencies.sh
Initialize configuration:
./clients/openframe-client/scripts/setup_dev_init_config.sh
Build and start services:
mvn clean install -DskipTests
./scripts/start-all-services.sh
For detailed setup instructions, see our Development Environment Guide.
General Principles:
Naming Conventions:
// Class names: PascalCase
public class DeviceManagementService {
// Constants: UPPER_SNAKE_CASE
private static final String DEFAULT_DEVICE_STATUS = "UNKNOWN";
private static final int MAX_RETRY_ATTEMPTS = 3;
// Variables and methods: camelCase
private final OrganizationRepository organizationRepository;
private String tenantId;
public DeviceResponse updateDeviceStatus(String deviceId, DeviceStatus status) {
// Implementation
}
// Boolean methods: use is/has/can prefix
public boolean isDeviceOnline(String deviceId) {
return checkDeviceStatus(deviceId) == DeviceStatus.ONLINE;
}
}
Spring Boot Specific Conventions:
// Controllers: Use @RestController and clear mappings
@RestController
@RequestMapping("/api/devices")
@Validated
public class DeviceController {
// Constructor injection (preferred over field injection)
private final DeviceService deviceService;
private final DeviceMapper deviceMapper;
public DeviceController(DeviceService deviceService, DeviceMapper deviceMapper) {
this.deviceService = deviceService;
this.deviceMapper = deviceMapper;
}
// HTTP methods: clear, RESTful endpoints
@GetMapping("/{deviceId}")
public ResponseEntity<DeviceResponse> getDevice(
@PathVariable String deviceId,
@AuthenticationPrincipal AuthPrincipal principal) {
DeviceResponse device = deviceService.getDevice(deviceId, principal.getTenantId());
return ResponseEntity.ok(device);
}
}
Multi-Tenant Security Requirements:
@AuthenticationPrincipal AuthPrincipal principal for tenant contextTypeScript Conventions:
// Interfaces: PascalCase with descriptive names
interface DeviceStatusProps {
deviceId: string;
status: 'online' | 'offline' | 'maintenance';
onStatusChange?: (deviceId: string, newStatus: string) => void;
}
// Components: PascalCase, functional components preferred
export const DeviceStatus: React.FC<DeviceStatusProps> = ({
deviceId,
status,
onStatusChange
}) => {
// Use descriptive variable names
const [isLoading, setIsLoading] = useState(false);
const [errorMessage, setErrorMessage] = useState<string | null>(null);
// Clear function names describing what they do
const handleStatusChange = useCallback(async (newStatus: string) => {
setIsLoading(true);
setErrorMessage(null);
try {
await deviceApi.updateStatus(deviceId, newStatus);
onStatusChange?.(deviceId, newStatus);
} catch (error) {
setErrorMessage('Failed to update device status');
} finally {
setIsLoading(false);
}
}, [deviceId, onStatusChange]);
return (
<div className={`device-status status-${status}`}>
{/* Component JSX */}
</div>
);
};
Format: <type>/<short-description>
Branch Types:
feature/ - New features or enhancementsbugfix/ - Bug fixes hotfix/ - Critical production fixesrefactor/ - Code refactoring without functional changesdocs/ - Documentation updatestest/ - Test additions or improvementschore/ - Maintenance tasks, dependency updatesExamples:
โ
Good branch names:
feature/multi-tenant-device-filtering
bugfix/jwt-token-validation-error
hotfix/memory-leak-in-stream-service
refactor/organization-service-cleanup
docs/api-documentation-update
test/integration-test-for-auth-flow
โ Poor branch names:
fix
update
john-work
temp-branch
bug
1. Before Creating a PR:
# Ensure your branch is up to date
git checkout main
git pull origin main
git checkout feature/your-feature-name
git rebase main
# Run tests locally
mvn clean verify
npm test # For frontend changes
# Run code quality checks
mvn spotbugs:check
npm run lint
2. PR Title and Description Format:
Title Format: [TYPE] Brief description of changes
Types:
[FEATURE] - New functionality[BUGFIX] - Bug resolution[HOTFIX] - Critical production fix[REFACTOR] - Code improvement without functional changes[DOCS] - Documentation updates[TEST] - Test-related changesExample PR Description:
## [FEATURE] Multi-tenant device filtering
### Summary
Implements tenant-aware device filtering to ensure users only see devices belonging to their organization and tenant.
### Changes Made
- Added tenant context validation in DeviceController
- Implemented tenant-scoped queries in DeviceRepository
- Updated DeviceService to enforce tenant isolation
- Added integration tests for multi-tenant scenarios
### Testing
- [x] Unit tests pass (`mvn test`)
- [x] Integration tests pass (`mvn verify`)
- [x] Manual testing with multiple tenants
- [x] Security tests for cross-tenant access prevention
### Security Considerations
- All database queries are scoped by tenant ID
- JWT token validation includes tenant context
- Added tests to prevent cross-tenant data access
### Breaking Changes
- None
### Related Issues
Closes #123
We follow the Conventional Commits specification:
Format: <type>[optional scope]: <description>
Types:
feat: - New featurefix: - Bug fixdocs: - Documentation changesstyle: - Code style changes (formatting, no logic changes)refactor: - Code refactoringtest: - Adding or updating testschore: - Maintenance tasksperf: - Performance improvementsci: - CI/CD changesbuild: - Build system changesExamples:
โ
Good commit messages:
feat(auth): implement multi-tenant JWT validation
fix(devices): resolve null pointer in device status update
docs(api): add authentication examples to API documentation
refactor(services): extract common tenant validation logic
test(integration): add tests for cross-tenant data isolation
chore(deps): upgrade Spring Boot to 3.3.0
โ Poor commit messages:
Update code
Fix bug
Changes
WIP
Done
@Test
void shouldFilterDevicesByTenantId() {
// Given
String tenantId = "tenant-123";
List<Device> tenantDevices = Arrays.asList(
createDevice("device-1", tenantId),
createDevice("device-2", tenantId)
);
when(deviceRepository.findByTenantId(tenantId)).thenReturn(tenantDevices);
// When
List<DeviceResponse> result = deviceService.getDevicesByTenant(tenantId);
// Then
assertThat(result).hasSize(2);
assertThat(result.get(0).getTenantId()).isEqualTo(tenantId);
}
Every contribution MUST maintain strict tenant isolation:
// โ
CORRECT: Always include tenant scoping
@GetMapping("/devices")
public ResponseEntity<List<DeviceResponse>> getDevices(
@AuthenticationPrincipal AuthPrincipal principal) {
List<DeviceResponse> devices = deviceService.getDevicesByTenant(principal.getTenantId());
return ResponseEntity.ok(devices);
}
// โ WRONG: Missing tenant context
@GetMapping("/devices")
public ResponseEntity<List<DeviceResponse>> getDevices() {
List<DeviceResponse> devices = deviceService.getAllDevices(); // Security violation!
return ResponseEntity.ok(devices);
}
@Valid, @NotNull, etc.)1. Planning and Design:
2. Development:
# Create feature branch
git checkout -b feature/your-feature-name
# Develop incrementally with frequent commits
git add -A
git commit -m "feat(component): implement core functionality"
# Push regularly for backup and collaboration
git push origin feature/your-feature-name
3. Testing and Quality Assurance:
# Run comprehensive test suite
mvn clean verify
npm run test:all
# Check code quality
mvn spotbugs:check
npm run lint
npm run type-check
# Manual testing
./scripts/start-all-services.sh
# Test feature functionality manually
Security Review:
Architecture Review:
Testing Review:
OpenMSP Slack Community:
#general#dev-help#code-review#architectureJoin the community: OpenMSP Slack
For New Contributors:
#new-contributors channel in SlackIssue Reporting: Use our GitHub issue templates for:
AI/ML Features:
Multi-Tenancy & Security:
Integration & Tools:
Developer Experience:
Look for issues labeled:
good-first-issue - Beginner-friendly tasksdocumentation - Documentation improvementstesting - Test coverage improvementsfrontend - UI/UX enhancementsEssential Reading:
External Resources:
By contributing to OpenFrame, you agree that your contributions will be licensed under the Flamingo AI Unified License v1.0.
Thank you for contributing to OpenFrame! Your efforts help build a better, more secure, and more powerful MSP platform. Together, we're creating the future of AI-powered IT operations.