mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
d02659d325
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
209 lines
6.8 KiB
Markdown
209 lines
6.8 KiB
Markdown
Outline is a fast, collaborative knowledge base built for teams. It's built with React and TypeScript in both frontend and backend, uses a real-time collaboration engine, and is designed for excellent performance and user experience. The backend is a Koa server with an RPC API and uses PostgreSQL and Redis. The application can be self-hosted or used as a cloud service.
|
||
|
||
There is a web client which is fully responsive and works on mobile devices.
|
||
|
||
**Monorepo Structure:**
|
||
|
||
- **`app/`** - React web application with MobX state management
|
||
- **`server/`** - Koa API server with Sequelize ORM and background workers
|
||
- **`shared/`** - Shared TypeScript types, utilities, and editor components
|
||
- **`plugins/`** - Plugin system for extending functionality
|
||
- **`public/`** - Static assets served directly
|
||
- **Various config files** - TypeScript, Vite, Vitest, Prettier, Oxlint configurations
|
||
|
||
Refer to /docs/ARCHITECTURE.md for detailed architecture documentation.
|
||
|
||
## Instructions
|
||
|
||
You're an expert in the following areas:
|
||
|
||
- TypeScript
|
||
- React and React Router
|
||
- MobX and MobX-React
|
||
- Node.js and Koa
|
||
- Sequelize ORM
|
||
- PostgreSQL
|
||
- Redis
|
||
- HTML, CSS and Styled Components
|
||
- Prosemirror (rich text editor)
|
||
- WebSockets and real-time collaboration
|
||
|
||
## General Guidelines
|
||
|
||
- Critical – Do not create new markdown (.md) files.
|
||
- Use early returns for readability.
|
||
- Emphasize type safety and static analysis.
|
||
- Follow consistent Prettier formatting.
|
||
- Do not replace smart quotes ("") or ('') with simple quotes ("").
|
||
- Do not add translation strings manually; they will be extracted automatically from the codebase.
|
||
|
||
## Dependencies and Upgrading
|
||
|
||
- Use yarn for all dependency management.
|
||
- After updating dependency versions, install to update lockfiles:
|
||
|
||
```bash
|
||
yarn install
|
||
```
|
||
|
||
- When adding a `resolutions` entry to address a security advisory in a transitive dependency, target only the specific vulnerable descriptors using the `name@npm:<range>` syntax rather than overriding the package globally. Inspect `yarn.lock` to find the exact ranges requested by upstream packages and add one entry per vulnerable range, e.g.:
|
||
|
||
```json
|
||
"resolutions": {
|
||
"qs@npm:^6.5.2": "^6.14.2",
|
||
"qs@npm:^6.11.0": "^6.14.2",
|
||
"qs@npm:^6.14.0": "^6.14.2"
|
||
}
|
||
```
|
||
|
||
This keeps overrides scoped to the affected dependents and avoids forcing unrelated consumers onto an incompatible version.
|
||
|
||
## TypeScript Usage
|
||
|
||
- Use strict mode.
|
||
- Avoid "unknown" unless absolutely necessary.
|
||
- Never use "any".
|
||
- Prefer type definitions; avoid type assertions (as, !).
|
||
- Always use curly braces for if statements.
|
||
- Avoid # for private properties.
|
||
- Prefer interface over type for object shapes.
|
||
|
||
## Classes & Code Organization
|
||
|
||
### Class Member Order
|
||
|
||
1. Public static variables
|
||
2. Public static methods
|
||
3. Public variables
|
||
4. Public methods
|
||
5. Protected variables & methods
|
||
6. Private variables & methods
|
||
|
||
### Exports
|
||
|
||
- Exported members must appear at the top of the file.
|
||
- Always use named exports for new components & classes.
|
||
- Document ALL public/exported functions with JSDoc.
|
||
|
||
## React Usage
|
||
|
||
- Use functional components with hooks.
|
||
- Event handlers should be prefixed with "handle", like "handleClick" for onClick.
|
||
- Avoid unnecessary re-renders by using React.memo, useMemo, and useCallback appropriately.
|
||
- Use descriptive prop types with TypeScript interfaces.
|
||
- Do not import React unless it is used directly.
|
||
- Use styled-components for component styling.
|
||
- Ensure high accessibility (a11y) standards using ARIA roles and semantic HTML.
|
||
|
||
## MobX State Management
|
||
|
||
- Use MobX stores for global state management.
|
||
- Keep stores in `app/stores/`.
|
||
- Use `observable`, `action`, and `computed` decorators appropriately.
|
||
- Prefer computed values over manual calculations in render.
|
||
- Keep business logic in stores, not components.
|
||
|
||
## Database & ORM
|
||
|
||
- Use Sequelize models in `server/models/`.
|
||
- Generate migrations with Sequelize CLI:
|
||
|
||
```bash
|
||
yarn sequelize migration:create --name=add-field-to-table
|
||
```
|
||
|
||
- Run migrations with `yarn db:migrate`.
|
||
- Use transactions for multi-table operations.
|
||
- Add appropriate indexes for query performance.
|
||
- Always handle database errors gracefully.
|
||
|
||
## API Design
|
||
|
||
- RESTful endpoints under `/api/`.
|
||
- Authentication endpoints under `/auth/`.
|
||
- Use consistent error responses.
|
||
- Validate request data using the validation middleware and schemas
|
||
- Use presenters to format API responses.
|
||
- Keep API routes thin, use model methods for business logic, or commands if logic spans multiple models.
|
||
|
||
## Authentication & Authorization
|
||
|
||
- JWT tokens for authentication.
|
||
- Policies in `server/policies/` for authorization.
|
||
- Use cancan-style ability checks.
|
||
- Use authenticated middleware for protected routes.
|
||
- Always verify user permissions before data access.
|
||
|
||
## Real-time Collaboration
|
||
|
||
- WebSocket connections for real-time updates.
|
||
- Use Y.js for collaborative editing.
|
||
- Handle connection state changes gracefully.
|
||
|
||
## Documentation
|
||
|
||
- All public/exported functions & classes must have JSDoc.
|
||
- Include:
|
||
- Description
|
||
- @param and @return (start lowercase, end with period)
|
||
- @throws if applicable
|
||
- Add a newline between the description and the @ block.
|
||
- Use correct punctuation.
|
||
|
||
## Testing
|
||
|
||
- Run tests with Vitest:
|
||
|
||
```bash
|
||
# Run a specific test file (preferred)
|
||
yarn test path/to/test.spec.ts
|
||
|
||
# Run every test (avoid)
|
||
yarn test
|
||
|
||
# Run test suites (avoid)
|
||
yarn test:app # All frontend tests
|
||
yarn test:server # All backend tests
|
||
yarn test:shared # All shared code tests
|
||
```
|
||
|
||
- Write unit tests for utilities and business logic in a collocated .test.ts file.
|
||
- Do not create new test directories
|
||
- Mock external dependencies appropriately in **mocks** folder.
|
||
- Aim for high code coverage but focus on critical paths.
|
||
|
||
## Code Quality
|
||
|
||
- Use Oxlint for linting: `yarn lint`
|
||
- Format code with Prettier: `yarn format`
|
||
- Check types with TypeScript: `yarn tsc`
|
||
- Pre-commit hooks run automatically via Husky.
|
||
- Fix linting issues before committing.
|
||
|
||
## Error Handling
|
||
|
||
- Use custom error classes in `server/errors.ts`.
|
||
- Always catch and handle errors appropriately.
|
||
- Log errors with appropriate context.
|
||
- Return user-friendly error messages.
|
||
- Never expose sensitive information in errors.
|
||
|
||
## Performance
|
||
|
||
- Use React.memo for expensive components.
|
||
- Implement pagination for large lists.
|
||
- Use database indexes effectively.
|
||
- Cache expensive computations.
|
||
- Monitor performance with appropriate tools.
|
||
- Lazy load routes and components where appropriate.
|
||
|
||
## Security
|
||
|
||
- Sanitize all user input.
|
||
- Always use `sanitizeUrl()` when setting `href` or `src` from user-controlled data in ProseMirror `toDOM` methods, regardless of whether it is imported via an alias or a relative path. Unlike React components, `toDOM` writes raw DOM and does not sanitize attribute values.
|
||
- Use CSRF protection.
|
||
- Use rateLimiter middleware for sensitive endpoints.
|
||
- Follow OWASP guidelines.
|
||
- Never store sensitive data in plain text.
|
||
- Use environment variables for secrets.
|