Thank you for your interest in contributing! This document provides guidelines and instructions for contributing to the project.
- Node.js 18+ (LTS recommended)
- npm 9+
- Clone the repository
- Install dependencies:
npm install
- Copy
.env.exampleto.envand configure your Notion API credentials - Start the development server:
npm run dev # Frontend only npm run dev:full # Frontend + backend
- Use strict TypeScript with all compiler checks enabled
- Prefer explicit types for function parameters and return values
- Use type imports:
import type { Type } from './module' - Avoid
any- useunknownand type guards when type is uncertain
- Use functional components with hooks
- Keep components focused and single-purpose
- Extract complex logic into custom hooks (
src/hooks/) - Use the Zustand store for global state (
src/store/useStore.ts)
src/
components/ # React components by category
canvas/ # Canvas view components
common/ # Shared components
filters/ # Filter-related components
tree/ # Tree view components
ui/ # Base UI components
views/ # Main view components
hooks/ # Custom React hooks
services/ # API and external service clients
store/ # Zustand state management
types/ # TypeScript type definitions
utils/ # Utility functions
- Files: PascalCase for components (
TreeNode.tsx), camelCase for utilities (dateUtils.ts) - Components: PascalCase (
TreeNode,FilterPanel) - Functions/Variables: camelCase (
calculateLayout,itemCount) - Types/Interfaces: PascalCase (
WorkItem,NotionConfig) - Constants: SCREAMING_SNAKE_CASE in
constants.ts(VIEW_LIMITS)
# Development
npm run dev # Start Vite dev server
npm run dev:server # Start backend API server
npm run dev:full # Start both frontend and backend
# Quality
npm run lint # Run ESLint
npm run lint:fix # Run ESLint with auto-fix
npm run typecheck # Run TypeScript type checking
npm run format # Format code with Prettier
npm run format:check # Check formatting
# Testing
npm run test # Run tests in watch mode
npm run test:run # Run tests once
npm run test:coverage # Run tests with coverage report
npm run test:ui # Run tests with UI
# Building
npm run build # Build frontend for production
npm run build:all # Build frontend and backend- Place test files next to the code they test:
utils/dateUtils.ts->utils/dateUtils.test.ts - Use descriptive test names that explain the expected behavior
- Follow the Arrange-Act-Assert pattern
- Mock external dependencies (API calls, localStorage, etc.)
import { describe, it, expect, vi } from 'vitest';
import { functionToTest } from './module';
describe('functionToTest', () => {
it('should return expected result for valid input', () => {
// Arrange
const input = 'test';
// Act
const result = functionToTest(input);
// Assert
expect(result).toBe('expected');
});
it('should handle edge cases', () => {
expect(functionToTest('')).toBe('default');
});
});Use conventional commit messages:
type(scope): description
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringtest: Adding or updating testschore: Maintenance tasks
Examples:
feat(canvas): add zoom controls to canvas view
fix(notion): handle rate limiting errors gracefully
docs: update README with new configuration options
refactor(store): simplify filter logic
The project uses Husky and lint-staged to run checks before commits:
- ESLint with auto-fix
- Prettier formatting
- TypeScript type checking
If a commit fails, fix the issues and try again.
- Create a feature branch from
main - Make your changes following the guidelines above
- Ensure all tests pass:
npm run test:run - Ensure linting passes:
npm run lint - Ensure build succeeds:
npm run build - Create a pull request with a clear description
## Summary
Brief description of the changes.
## Changes
- List of specific changes made
## Testing
- How the changes were tested
- Any new tests added
## Screenshots (if applicable)
Include screenshots for UI changes.- Global state is managed with Zustand (
src/store/useStore.ts) - The store includes selectors for computed values (
getFilteredItems,getTreeNodes) - Prefer derived state over duplicated state
Notion API -> notionService -> Zustand Store -> React Components
|
Cache Layer
(memory + localStorage)
- Use the utilities from
src/utils/errors.tsfor consistent error handling - Use type guards from
src/utils/typeGuards.tsfor type-safe checks - Log errors using
src/utils/logger.tsfor consistent formatting
If you have questions about contributing, please open an issue for discussion.