A one-page condensed reference for VerifyWise development standards. For detailed explanations, see the full documentation in README.md.
| Element | Convention | Example |
|---|---|---|
| Variables & Functions | camelCase | getUserData, isValid |
| Components & Classes | PascalCase | UserProfile, AuthService |
| Interfaces | PascalCase (optional I prefix) |
UserProps, IChipProps |
| Constants | UPPER_SNAKE_CASE | MAX_RETRIES, API_BASE_URL |
| Files (Components) | ComponentName/index.tsx |
PluginCard/index.tsx |
| Files (Utilities) | camelCase | formatDate.ts |
| Folders (Components) | PascalCase | PluginCard/, IconButton/ |
| Folders (Utilities) | camelCase | hooks/, redux/ |
| Database Tables | snake_case | user_profiles |
| Python Variables | snake_case | user_name, get_user_data |
// Always use explicit types
const users: User[] = [];
// Avoid 'any' - use 'unknown' and narrow
function processData(data: unknown): ProcessedData {
if (isValidData(data)) {
return transform(data);
}
throw new Error('Invalid data');
}
// Use interfaces for objects
interface User {
id: string;
name: string;
email: string;
}
// Use type for unions/intersections
type Status = 'pending' | 'active' | 'inactive';// 1. Imports (external, internal, types)
import { useState, useCallback } from 'react';
import { Box, Typography } from '@mui/material';
import { useUser } from '@/hooks/useUser';
import type { UserProps } from './types';
// 2. Interface (if not in separate file)
interface Props {
userId: string;
onUpdate?: (user: User) => void;
}
// 3. Component (function declaration)
export function UserCard({ userId, onUpdate }: Props) {
// Hooks first
const { user, isLoading } = useUser(userId);
const [isEditing, setIsEditing] = useState(false);
// Handlers
const handleSave = useCallback(() => {
// implementation
}, []);
// Early returns for loading/error states
if (isLoading) return <Skeleton />;
if (!user) return null;
// Main render
return (
<Box>
<Typography>{user.name}</Typography>
</Box>
);
}import { Request, Response } from "express";
import { STATUS_CODE } from "../utils/statusCode.utils";
import { logProcessing, logSuccess, logFailure } from "../utils/logger/logHelper";
export async function getEntity(req: Request, res: Response): Promise<any> {
logProcessing({
description: "starting getEntity",
functionName: "getEntity",
fileName: "entity.ctrl.ts",
userId: req.userId!,
tenantId: req.tenantId!,
});
try {
const { id } = req.params;
const tenantId = req.tenantId!;
const entity = await getEntityByIdQuery(id, tenantId);
if (!entity) {
return res.status(404).json(STATUS_CODE[404]({ message: "Not found" }));
}
await logSuccess({
eventType: "Read",
description: "Retrieved entity",
functionName: "getEntity",
fileName: "entity.ctrl.ts",
userId: req.userId!,
tenantId: req.tenantId!,
});
return res.status(200).json(STATUS_CODE[200](entity));
} catch (error) {
await logFailure({
eventType: "Read",
description: "Failed to retrieve entity",
functionName: "getEntity",
fileName: "entity.ctrl.ts",
error: error as Error,
userId: req.userId!,
tenantId: req.tenantId!,
});
return res.status(500).json(STATUS_CODE[500]((error as Error).message));
}
}from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
router = APIRouter(prefix="/users", tags=["users"])
class UserResponse(BaseModel):
id: str
name: str
email: str
@router.get("/{user_id}", response_model=UserResponse)
async def get_user(
user_id: str,
db: Session = Depends(get_db)
) -> UserResponse:
user = await user_service.get_by_id(db, user_id)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user| Element | Standard |
|---|---|
| Primary color | #13715B |
| Font family | Geist |
| Base font size | 13px |
| Spacing base | 2px (theme.spacing(4) = 8px) |
| Border radius | 4px |
| Border color | #d0d5dd |
| Button height | 34px, sentence case |
| Icon library | lucide-react (NOT @mui/icons-material) |
| Icon sizes | 14px (tables), 16px (buttons), 18px (nav), 20-24px (headers) |
| Shadows | Borders on cards; shadows only on floating elements |
| Text case | Sentence case everywhere (never Title Case or ALL CAPS) |
See Design System for full documentation.
Before submitting a PR, ensure:
- Code deployed and tested locally
- Self-review completed
- Issue number included
- PR labeled correctly
- No hardcoded values
- UI elements use theme references
- PR addresses single feature
- Screenshots/videos for UI changes
- Tests written/updated
- No console.log statements
- No sensitive data exposed
- Never store secrets in code - use environment variables
- Always validate and sanitize user input
- Never expose internal error details to clients
- Always use parameterized queries (Sequelize handles this)
- Never disable security headers in production
- Always hash passwords with bcrypt (cost factor 12+)
- Never log sensitive data (passwords, tokens, PII)
- Minimum Coverage: 80%
- Required Tests:
- Unit tests for business logic
- Integration tests for API endpoints
- Component tests for UI elements
- Test Naming:
describe('ComponentName', () => { it('should do X when Y', () => {}) })
type(scope): description
[optional body]
[optional footer]
Types: feat, fix, docs, style, refactor, test, chore
Examples:
feat(auth): add password reset functionality
fix(dashboard): resolve chart rendering issue
docs(api): update endpoint documentation
| Principle | Meaning |
|---|---|
| DRY | Don't Repeat Yourself - extract common logic |
| KISS | Keep It Simple, Stupid - prefer simple solutions |
| YAGNI | You Aren't Gonna Need It - don't add unused features |
| SRP | Single Responsibility - one reason to change |
| Boy Scout Rule | Leave code cleaner than you found it |