diff --git a/AGENTS.md b/AGENTS.md index ae5c4970d1..6491a0fa46 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,7 +7,7 @@ This guide provides comprehensive information for AI agents (like Cursor) workin **Actual Budget** is a local-first personal finance tool written in TypeScript/JavaScript. It's 100% free and open-source with synchronization capabilities across devices. - **Repository**: https://github.com/actualbudget/actual -- **Community Docs**: https://github.com/actualbudget/actual/tree/master/packages/docs or https://actualbudget.org/docs +- **Community Docs**: Documentation is part of the monorepo at `packages/docs/`. Published at https://actualbudget.org/docs - **License**: MIT - **Primary Language**: TypeScript (with React) - **Build System**: Yarn 4 workspaces (monorepo) @@ -173,6 +173,19 @@ Custom ESLint rules specific to Actual. - `typography`: Typography rules - `prefer-if-statement`: Prefers explicit if statements +#### 10. **docs** (`packages/docs/`) + +Documentation website built with Docusaurus. + +- Documentation is part of the monorepo +- Built with Docusaurus 3 +- Commands: + ```bash + yarn workspace docs start + yarn workspace docs build + yarn start:docs # From root + ``` + ## Development Workflow ### 1. Making Changes @@ -201,9 +214,6 @@ yarn test:debug # Run tests for a specific package yarn workspace loot-core run test - -# Run a specific test file (watch mode) -yarn workspace loot-core run test path/to/test.test.ts ``` **E2E Tests (Playwright)** @@ -382,6 +392,7 @@ describe('ComponentName', () => { - `/CONTRIBUTING.md` - Points to community docs - `/upcoming-release-notes/` - Release notes for next version - `/CODEOWNERS` - Code ownership definitions +- `/packages/docs/` - Documentation website (Docusaurus) ### Build Artifacts (Don't Edit) @@ -403,6 +414,8 @@ describe('ComponentName', () => { - `packages/desktop-client/e2e/` - End-to-end tests - `packages/component-library/src/` - Reusable components - `packages/component-library/src/icons/` - Icon components (auto-generated, don't edit) +- `packages/docs/docs/` - Documentation source files (Markdown) +- `packages/docs/docs/contributing/` - Developer documentation ## Common Development Tasks @@ -412,9 +425,6 @@ describe('ComponentName', () => { # Run all tests across all packages (recommended) yarn test -# Unit test for a specific file in loot-core (watch mode) -yarn workspace loot-core run test src/path/to/file.test.ts - # E2E test for a specific file yarn workspace @actual-app/web run playwright test accounts.test.ts --browser=chromium ``` diff --git a/packages/docs/docs-sidebar.js b/packages/docs/docs-sidebar.js index e7c9cecb70..0673416927 100644 --- a/packages/docs/docs-sidebar.js +++ b/packages/docs/docs-sidebar.js @@ -307,6 +307,10 @@ const sidebars = { 'contributing/project-details/advice', ], }, + 'contributing/development-setup', + 'contributing/testing', + 'contributing/code-style', + 'contributing/troubleshooting', 'contributing/i18n', 'contributing/preview-builds', 'contributing/releasing', diff --git a/packages/docs/docs/config/index.md b/packages/docs/docs/config/index.md index 4986f44a9c..e52ab921ee 100644 --- a/packages/docs/docs/config/index.md +++ b/packages/docs/docs/config/index.md @@ -55,7 +55,7 @@ If you want Actual to serve over HTTPS, you can set this key to an object with t - `key`: The path to the private key file. (environment variable: `ACTUAL_HTTPS_KEY`) - `cert`: The path to the certificate file. (environment variable: `ACTUAL_HTTPS_CERT`) -- any other options from Node’s [`tls.createServer()`](https://nodejs.org/docs/latest-v16.x/api/tls.html#tlscreateserveroptions-secureconnectionlistener), [`tls.createSecureContext()`](https://nodejs.org/docs/latest-v16.x/api/tls.html#tlscreatesecurecontextoptions), or [`http.createServer()`](https://nodejs.org/docs/latest-v16.x/api/http.html#httpcreateserveroptions-requestlistener) functions (optional, most people won’t need to set any of these). +- any other options from Node's [`tls.createServer()`](https://nodejs.org/api/tls.html#tlscreateserveroptions-secureconnectionlistener), [`tls.createSecureContext()`](https://nodejs.org/api/tls.html#tlscreatesecurecontextoptions), or [`http.createServer()`](https://nodejs.org/api/http.html#httpcreateserveroptions-requestlistener) functions (optional, most people won't need to set any of these). See [Activating HTTPS](/config/https.md) for more information on how to get HTTPS working. diff --git a/packages/docs/docs/contributing/code-style.md b/packages/docs/docs/contributing/code-style.md new file mode 100644 index 0000000000..d590402e88 --- /dev/null +++ b/packages/docs/docs/contributing/code-style.md @@ -0,0 +1,147 @@ +--- +title: Code Style and Conventions +--- + +This guide outlines the coding conventions and style guidelines for contributing to Actual Budget. Following these guidelines helps maintain consistency and code quality across the codebase. + +## TypeScript Guidelines + +### Type Usage + +- **Use TypeScript for all code**: All new code should be written in TypeScript +- **Prefer `type` over `interface`**: Use type aliases instead of interfaces when possible +- **Avoid `enum`**: Use objects or maps instead of enums +- **Avoid `any` or `unknown`**: Only use when absolutely necessary +- **Look for existing types**: Check `packages/loot-core/src/types/` for existing type definitions +- **Avoid type assertions**: Prefer `satisfies` over `as` or `!` for type narrowing +- **Use inline type imports**: `import { type MyType } from '...'` + +### Naming Conventions + +- **Descriptive variable names**: Use auxiliary verbs for boolean variables (e.g., `isLoaded`, `hasError`) +- **Named exports**: Use named exports for components and utilities (avoid default exports except in specific cases) + +### Code Structure + +- **Functional programming**: Prefer functional and declarative programming patterns - avoid classes +- **Pure functions**: Use the `function` keyword for pure functions +- **Modularization**: Prefer iteration and modularization over code duplication +- **File structure**: Structure files as: exported component/page, helpers, static content, types +- **Component files**: Create new components in their own files + +## React Patterns + +### Component Definition + +- **Don't use `React.FunctionComponent` or `React.FC`**: Type props directly +- **Don't use `React.*` patterns**: Use named imports instead (e.g., `import { useState } from 'react'`) + +### Component Example + +```typescript +import { type ComponentType } from 'react'; +// ... other imports + +type MyComponentProps = { + prop1: string; + prop2: number; +}; + +export function MyComponent({ prop1, prop2 }: MyComponentProps) { + // Component logic + return ( + // JSX + ); +} +``` + +### Custom Hooks + +Use custom hooks from `src/hooks` instead of importing directly from react-router or react-redux: + +- `useNavigate()` from `src/hooks` (not react-router) +- `useDispatch()`, `useSelector()`, `useStore()` from `src/redux` (not react-redux) + +### Other React Guidelines + +- **Avoid unstable nested components**: Don't define components inside other components +- **Use `satisfies` for type narrowing**: Prefer `satisfies` over type assertions +- **Use `` instead of `` tags**: For internal navigation + +### JSX Style + +- **Declarative JSX**: Keep JSX minimal and readable +- **Avoid unnecessary curly braces**: In conditionals when not needed +- **Concise syntax**: Use concise syntax for simple statements +- **Explicit expressions**: Prefer explicit expressions (`condition && `) + +## Platform-Specific Code + +- **Don't directly reference platform-specific imports**: Avoid importing `.api`, `.web`, or `.electron` directly +- **Use conditional exports**: Use conditional exports in `loot-core` for platform-specific code +- **Build-time resolution**: Platform resolution happens at build time via package.json exports + +## Restricted Patterns + +### Never Use + +- **`uuid` without destructuring**: Use `import { v4 as uuidv4 } from 'uuid'` +- **Direct color imports**: Use theme instead of importing colors directly +- **`@actual-app/web/*` imports in `loot-core`**: Don't import from web package in core + +## File Structure Patterns + +### Component File Structure + +```typescript +import { type ComponentType } from 'react'; +// ... other imports + +type MyComponentProps = { + // Props definition +}; + +export function MyComponent({ prop1, prop2 }: MyComponentProps) { + // Component logic + return ( + // JSX + ); +} +``` + +### Test File Structure + +```typescript +import { describe, it, expect, beforeEach } from 'vitest'; +// ... imports + +describe('ComponentName', () => { + it('should behave as expected', () => { + // Test logic + expect(result).toBe(expected); + }); +}); +``` + +## Internationalization (i18n) + +- **Use `Trans` component**: Prefer `Trans` component instead of `t()` function when possible +- **Translate all user-facing strings**: All user-facing strings must be translated +- **Generate i18n files**: Run `yarn generate:i18n` to generate translation files +- **ESLint enforcement**: Custom ESLint rules enforce translation usage + +## Code Quality Checklist + +Before committing changes, ensure: + +- [ ] `yarn typecheck` passes +- [ ] `yarn lint:fix` has been run +- [ ] Relevant tests pass +- [ ] User-facing strings are translated +- [ ] Prefer `type` over `interface` + +## Additional Resources + +- [TypeScript Handbook](https://www.typescriptlang.org/docs/) +- [React Documentation](https://react.dev/) +- [ESLint Configuration](./project-details/architecture.md) - See project structure for ESLint setup diff --git a/packages/docs/docs/contributing/development-setup.md b/packages/docs/docs/contributing/development-setup.md new file mode 100644 index 0000000000..69f412f341 --- /dev/null +++ b/packages/docs/docs/contributing/development-setup.md @@ -0,0 +1,200 @@ +--- +title: Development Setup +--- + +This guide will help you set up your development environment for contributing to Actual. + +## Prerequisites + +Before you begin, ensure you have the following installed: + +- **Node.js**: Version 22 or greater. You can download it from the [Node.js website](https://nodejs.org/en/download) (we recommend the LTS version). + - Consider using a version manager like [nvm](https://github.com/nvm-sh/nvm) or [asdf](https://asdf-vm.com) to manage multiple Node.js versions. + - On Windows, during Node.js installation, be sure to select _Automatically install the necessary tools_ from the _Tools for Native Modules_ page. This is required to build better-sqlite3. + +- **Yarn**: Version 4.9.1 or greater. Yarn is the package manager used by Actual. + - The project uses Yarn 4 workspaces (monorepo structure). + +- **Git**: Required for cloning the repository and version control. + +## Initial Setup + +1. Clone the Actual repository: + + ```bash + git clone https://github.com/actualbudget/actual.git + cd actual + ``` + +2. Install all dependencies: + + ```bash + yarn install + ``` + + This will install dependencies for all packages in the monorepo. + +3. Verify your setup by running type checking: + ```bash + yarn typecheck + ``` + +## Essential Development Commands + +All commands should be run from the **root directory** of the repository. Never run yarn commands from child workspace directories. + +### Type Checking + +```bash +# Run TypeScript type checking (ALWAYS run before committing) +yarn typecheck +``` + +### Linting and Formatting + +```bash +# Check for linting and formatting issues +yarn lint + +# Auto-fix linting and formatting issues +yarn lint:fix +``` + +### Testing + +```bash +# Run all tests across all packages +yarn test + +# Run tests without cache (for debugging) +yarn test:debug +``` + +For more details on testing, see the [Testing Guide](./testing.md). + +### Starting Development Servers + +```bash +# Start browser development server +yarn start +# or explicitly: +yarn start:browser + +# Start with sync server (for testing sync functionality) +yarn start:server-dev + +# Start desktop app development +yarn start:desktop +``` + +### Building + +```bash +# Build browser version +yarn build:browser + +# Build desktop app +yarn build:desktop + +# Build API package +yarn build:api + +# Build sync server +yarn build:server +``` + +## Workspace Structure + +Actual uses Yarn workspaces to manage a monorepo with multiple packages. For detailed information about each package, see the [Project Structure](./project-details/index.md) documentation. + +## Running Workspace-Specific Commands + +To run commands for a specific workspace, use: + +```bash +yarn workspace run +``` + +Examples: + +```bash +# Run tests for loot-core +yarn workspace loot-core run test + +# Start the docs development server +yarn workspace docs start + +# Build the API package +yarn workspace @actual-app/api build +``` + +## Common Development Tasks + +### Running Specific Tests + +See [Testing Guide](./testing.md). + +### Debugging + +```bash +# Run tests in debug mode (without cache) +yarn test:debug + +# Run E2E tests with headed browser +yarn workspace @actual-app/web run playwright test --headed --debug accounts.test.ts +``` + +### Type Checking + +TypeScript uses project references. Always run `yarn typecheck` from the root to check all packages. + +### Building for Production + +```bash +# Browser build +yarn build:browser + +# Desktop build +yarn build:desktop + +# API build +yarn build:api + +# Sync server build +yarn build:server +``` + +## Development Workflow + +When making changes: + +1. Read relevant files to understand the current implementation +2. Make focused, incremental changes +3. Run type checking: `yarn typecheck` +4. Run linting: `yarn lint:fix` +5. Run relevant tests +6. Fix any linter errors that are introduced + +For more details, see the [Development Workflow](./index.md#development-workflow) section. + +## Troubleshooting + +If you encounter issues: + +- **Type errors**: Run `yarn typecheck` to see all type errors +- **Linter errors**: Run `yarn lint:fix` to auto-fix many issues +- **Test failures**: See the [Testing Guide](./testing.md) for debugging tips +- **Build failures**: Clean build artifacts and reinstall dependencies: + ```bash + rm -rf packages/*/dist packages/*/lib-dist packages/*/build + yarn install + ``` + +For more troubleshooting help, see the [Troubleshooting Guide](./troubleshooting.md). + +## Next Steps + +- Read the [Contributing Guide](./index.md) for information about submitting changes +- Review the [Code Style Guide](./code-style.md) for coding conventions +- Check out the [Testing Guide](./testing.md) for testing strategies +- Explore the [Project Structure](./project-details/index.md) to understand the codebase organization diff --git a/packages/docs/docs/contributing/index.md b/packages/docs/docs/contributing/index.md index c9f89fcee3..e183bf457b 100644 --- a/packages/docs/docs/contributing/index.md +++ b/packages/docs/docs/contributing/index.md @@ -54,6 +54,28 @@ Here are some initial guidelines for how contributions will be treated: - @twk3 - @UnderKoen +### Getting Started + +Before you begin contributing, make sure you have your development environment set up: + +1. **Set up your development environment**: Follow the [Development Setup Guide](./development-setup.md) to install prerequisites and get started. +2. **Understand the codebase**: Review the [Project Structure](./project-details/index.md) to understand how the codebase is organized. +3. **Learn the coding conventions**: Read the [Code Style Guide](./code-style.md) to understand our coding standards. +4. **Familiarize yourself with testing**: Check out the [Testing Guide](./testing.md) to learn how to write and run tests. + +### Development Workflow + +When making changes to Actual, follow this workflow: + +1. **Read relevant files**: Understand the current implementation before making changes. +2. **Make focused, incremental changes**: Keep changes small and focused on a single feature or bugfix. +3. **Run type checking**: Always run `yarn typecheck` before committing to catch type errors. +4. **Run linting**: Run `yarn lint:fix` to ensure code follows style guidelines. +5. **Run relevant tests**: Run tests for the code you've changed (`yarn test` for all tests, or workspace-specific commands). +6. **Fix any issues**: Address any type errors, linter errors, or test failures before submitting your PR. + +For more details, see the [Development Setup Guide](./development-setup.md) and [Testing Guide](./testing.md). + ### The Project Layout The layout of the codebase in Actual Budget takes a bit of getting used to and finding things at first can be a little tricky. We have put together a help [document](./project-details/index.md) that shows the structure of the project. While this isn't 100% complete it will give you a good starting point for your development. @@ -121,3 +143,11 @@ Try to phrase your message as a command, e.g. "Add option to include exchange ra The goal of the UI is to be minimalistic, but expose more advanced features progressively as the user interacts with the product (for example: the notes button is not visible by default if an account has no notes, but it becomes persistent visible if there are notes). We advocate for a similar approach in other places too. We are against adding a button/user setting for every little piece of UI (sizes, paddings, margins, etc.) as that goes against this simple design philosophy. The settings screen needs to also remain a place where core settings lives, we don't really want to have a myriad of options in here for each and every setting within the UI, doing that makes the code un-manageable for future contributors and clutters up and confuses things for the users of Actual Budget. + +## Additional Resources + +- [Development Setup](./development-setup.md) - Set up your development environment +- [Testing Guide](./testing.md) - Learn about testing strategies and how to run tests +- [Code Style Guide](./code-style.md) - Coding conventions and style guidelines +- [Troubleshooting](./troubleshooting.md) - Common issues and solutions +- [Project Structure](./project-details/index.md) - Understanding the codebase organization diff --git a/packages/docs/docs/contributing/project-details/architecture.md b/packages/docs/docs/contributing/project-details/architecture.md index f7a0712683..1682d2bb99 100644 --- a/packages/docs/docs/contributing/project-details/architecture.md +++ b/packages/docs/docs/contributing/project-details/architecture.md @@ -1,9 +1,43 @@ # Architecture Notes -If you wish to contribute to actual, these details are not essential but can be useful for navigating the structure of the code. +If you wish to contribute to Actual, these details are not essential but can be useful for navigating the structure of the code. -When actual runs, it runs the front-end react based web app, as well as a local in-browser database server. You may see these informally referred to as 'frontend' and 'backend' - not to be confused with the sync-server or some other type of remote 'backend' (which doesn't exist). +## Overview -In the web app, this background server runs in a [web worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers), and in the electron app it spins up a [background process](https://nodejs.org/dist/latest-v16.x/docs/api/child_process.html#child_processforkmodulepath-args-options) which communicates over [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API). +When Actual runs, it runs the front-end React-based web app, as well as a local in-browser database server. You may see these informally referred to as 'frontend' and 'backend' - not to be confused with the sync-server or some other type of remote 'backend' (which doesn't exist). -The code which is used by this background server, as well as code which is shared across the web app and desktop versions of actual typically lives inside the `loot-core` package. +## Runtime Architecture + +### Web App + +In the web app, the background server runs in a [web worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers). This allows the database operations to run in a separate thread, keeping the UI responsive. + +### Electron App + +In the Electron app, the background server runs as a [Node.js child process](https://nodejs.org/api/child_process.html) which communicates with the frontend over [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API). This allows the desktop app to use full Node.js capabilities while maintaining security through process isolation. + +Details of the motivation behind the usage of WebSockets in the Electron app can be found in [Pull Request #1003](https://github.com/actualbudget/actual/pull/1003). + +## Core Package Structure + +The code which is used by this background server, as well as code which is shared across the web app and desktop versions of Actual typically lives inside the `loot-core` package. + +### Platform-Specific Exports + +The `loot-core` package uses conditional exports to provide platform-specific code: + +- **Browser exports**: Code that runs in the web worker or browser environment +- **Node exports**: Code that runs in the Electron background process or Node.js API +- **Shared code**: Code that works in both environments + +Platform resolution happens at build time via `package.json` exports. Don't directly reference platform-specific imports (`.api`, `.web`, `.electron`) - use the conditional exports instead. + +## Build System + +- **Vite**: Used for bundling the web app and desktop client +- **TypeScript**: All code is written in TypeScript with strict type checking +- **Yarn Workspaces**: Monorepo structure managed with Yarn 4 + +## Data Storage + +Actual uses SQLite for local data storage. The database is created from a default template and then migrations are applied to bring it to the current schema version. See the [Database Details](./database.md) documentation for more information. diff --git a/packages/docs/docs/contributing/project-details/index.md b/packages/docs/docs/contributing/project-details/index.md index 56731f9c54..b37fdd5399 100644 --- a/packages/docs/docs/contributing/project-details/index.md +++ b/packages/docs/docs/contributing/project-details/index.md @@ -1,43 +1,62 @@ # The Actual Project Structure -Actual is made up of lots of different _packages_. This article covers how they all fit together to form the project you know as Actual Budget. +Actual is made up of lots of different _packages_ organized as a monorepo using Yarn workspaces. This article covers how they all fit together to form the project you know as Actual. All of our repositories can be found in the [Actual Budget](https://github.com/actualbudget) organization on GitHub, within that organization you will then find the repository containing the code for [Actual, Actual Server and the Docs](https://github.com/actualbudget/actual). -## Actual +The Actual monorepo contains the following main packages: -This repository holds all of the front end code for the Actual Budget application, along with the syncing engine and the importers for YNAB4 and YNAB5 (also commonly referred to as nYNAB). +### 1. loot-core (`packages/loot-core/`) -``` -├── actual - └── Packages - └── api - └── crdt - └── desktop-client - └── desktop-electron - └── loot-core - └── sync-server - ... -│ -``` +The core application logic that runs on any platform. -### Desktop Client +- **Purpose**: Business logic, database operations, and calculations +- **Platform**: Platform-agnostic code that works in both browser and Node.js environments +- **Exports**: Provides conditional exports for browser and node environments +- **Key Directories**: + - `src/client/` - Client-side core logic + - `src/server/` - Server-side core logic + - `src/shared/` - Shared utilities + - `src/types/` - Type definitions + - `migrations/` - Database migration files -While this is called Desktop Client, this actually has nothing to do with the desktop, this package forms the front end code for the Actual Web app, the code that you see when you load Actual in your browser. +### 2. desktop-client (`packages/desktop-client/` - aliased as `@actual-app/web`) -### Desktop Electron +The React-based UI for web and desktop. -This is the source code for the Desktop application. It's a wrapper that allows for a stable use of the Actual Web App locally with or without the internet or a sync-server. It is unlikely you will need to make changes here. +- **Purpose**: Forms the front-end code for the Actual web app - the code you see when you load Actual in your browser +- **Note**: Despite the name "desktop-client", this package is actually the web UI used by both browser and desktop apps +- **Technology**: React components using functional programming patterns, Vite for bundling +- **Key Directories**: + - `src/components/` - React components + - `src/hooks/` - Custom React hooks + - `e2e/` - End-to-end tests -### Loot Core +### 3. desktop-electron (`packages/desktop-electron/`) -The shared underlying functionality component used by both the web/desktop frontend and the in-browser database server. +Electron wrapper for the desktop application. -### Sync Server +- **Purpose**: Provides the desktop application wrapper that allows stable use of the Actual Web App locally with or without internet or a sync-server +- **Technology**: Electron for window management and native OS integration +- **Note**: It is unlikely you will need to make changes here unless working on Electron-specific features -The Sync Server, also known as Actual Server, holds all of the code for the synchronization element of the Actual Budget application. Actual server has a dependency of Actual so when you deploy Actual Server to your hosting method of choice, be that Fly, Local etc. and run `yarn build:server` and `yarn install`, the Actual client will be installed as a dependency into the Actual Server deployment. +### 4. api (`packages/api/` - aliased as `@actual-app/api`) -You can see this in the [package.json](https://github.com/actualbudget/actual/blob/master/packages/sync-server/package.json) file; +Public API for programmatic access to Actual. + +- **Purpose**: Node.js API package designed for integrations and automation +- **Use Cases**: Custom importers, data exporters, automation scripts + +### 5. sync-server (`packages/sync-server/` - aliased as `@actual-app/sync-server`) + +Synchronization server for multi-device support. + +- **Purpose**: Handles synchronization of budget data across multiple devices +- **Technology**: Express-based server, currently transitioning to TypeScript (mostly JavaScript) +- **Dependency**: Has a dependency on `@actual-app/web` (the desktop-client package) +- **Deployment**: When you deploy Actual Server and run `yarn build:server` and `yarn install`, the Actual client is installed as a dependency + +You can see this in the [package.json](https://github.com/actualbudget/actual/blob/master/packages/sync-server/package.json) file: ```json "dependencies": { @@ -46,4 +65,58 @@ You can see this in the [package.json](https://github.com/actualbudget/actual/bl }, ``` -The workspace reference ensures that changes to @actual-app/web are reflected in your server deployment. If you see any discrepencies it means you need to run `yarn build:server` to compile the latest. +The workspace reference ensures that changes to `@actual-app/web` are reflected in your server deployment. If you see any discrepancies, run `yarn build:server` to compile the latest. + +### 6. component-library (`packages/component-library/` - aliased as `@actual-app/components`) + +Reusable React UI components. + +- **Purpose**: Shared components like Button, Input, Menu, etc. +- **Features**: Theme system, design tokens, and icon components +- **Icons**: Contains 375+ icons in SVG/TSX format (auto-generated, don't edit manually) +- **Key Directories**: + - `src/` - Component source files + - `src/icons/` - Icon components (auto-generated) + +### 7. crdt (`packages/crdt/` - aliased as `@actual-app/crdt`) + +CRDT (Conflict-free Replicated Data Type) implementation for data synchronization. + +- **Purpose**: Core sync logic for handling concurrent edits across devices +- **Technology**: Protocol buffers for serialization +- **Use**: Used by the sync-server for conflict-free data synchronization + +### 8. plugins-service (`packages/plugins-service/`) + +Service for handling plugins/extensions. + +- **Purpose**: Manages plugin functionality and extensions + +### 9. eslint-plugin-actual (`packages/eslint-plugin-actual/`) + +Custom ESLint rules specific to Actual. + +- **Purpose**: Enforces Actual-specific coding standards +- **Rules**: + - `no-untranslated-strings` - Enforces i18n usage + - `prefer-trans-over-t` - Prefers Trans component over t() function + - `prefer-logger-over-console` - Enforces using logger instead of console + - `typography` - Typography rules + - `prefer-if-statement` - Prefers explicit if statements + +### 10. docs (`packages/docs/`) + +Documentation website built with Docusaurus. + +- **Purpose**: The Actual documentation website +- **Technology**: Docusaurus 3 for static site generation + +## Working with Packages + +To run commands for a specific package, use: + +```bash +yarn workspace run +``` + +For more information about development workflows, see the [Development Setup Guide](../development-setup.md). diff --git a/packages/docs/docs/contributing/testing.md b/packages/docs/docs/contributing/testing.md new file mode 100644 index 0000000000..a29f21c1dc --- /dev/null +++ b/packages/docs/docs/contributing/testing.md @@ -0,0 +1,181 @@ +--- +title: Testing +--- + +Actual uses a comprehensive testing strategy to ensure code quality and reliability. This guide covers how to run tests, write tests, and debug test failures. + +## Testing Overview + +The project uses multiple testing frameworks: + +- **Vitest** - Unit testing framework +- **Playwright** - End-to-end (E2E) testing +- **Lage** - Task runner for running tests across the monorepo efficiently + +## Running Tests + +### Running All Tests + +```bash +# Run all tests across all packages (recommended) +yarn test + +# Run tests without cache (for debugging/CI) +yarn test:debug +``` + +The `yarn test` command uses Lage to run tests in parallel across all workspaces. This provides: + +- **Parallel execution**: Tests run simultaneously across packages for faster feedback +- **Smart caching**: Test results are cached in `.lage/` directory to skip unchanged packages +- **Dependency awareness**: Understands workspace dependencies and execution order + +### Running Tests for a Specific Package + +```bash +# Run tests for loot-core +yarn workspace loot-core run test + +# Run tests for the API package +yarn workspace @actual-app/api run test + +# Run tests for desktop-client +yarn workspace @actual-app/web run test +``` + +### Running a Specific Test File + +```bash +# Run E2E test for a specific file +yarn workspace @actual-app/web run playwright test accounts.test.ts +``` + +## Unit Tests (Vitest) + +Unit tests are located alongside source files or in `__tests__` directories. Test files use the following naming conventions: + +- `.test.ts` - TypeScript test files +- `.test.tsx` - React component test files +- `.spec.js` - JavaScript test files (legacy) + +### Writing Unit Tests + +```typescript +import { describe, it, expect, beforeEach } from 'vitest'; +// ... other imports + +describe('ComponentName', () => { + beforeEach(() => { + // Setup code + }); + + it('should behave as expected', () => { + // Test logic + expect(result).toBe(expected); + }); +}); +``` + +### Testing Best Practices + +- **Minimize mocking**: Prefer real implementations over mocks when possible +- **Use descriptive test names**: Test names should clearly describe what is being tested +- **Vitest globals**: `describe`, `it`, `expect`, `beforeEach`, etc. are available globally +- **Sync-server tests**: For sync-server tests, globals are explicitly defined in config + +## End-to-End Tests (Playwright) + +E2E tests are located in `packages/desktop-client/e2e/` and use Playwright as the test runner. + +### Running E2E Tests + +```bash +# Run E2E tests for web +yarn e2e + +# Desktop Electron E2E (includes full build) +yarn e2e:desktop + +# Run E2E tests for a specific package +yarn workspace @actual-app/web e2e + +# Run specific E2E test with headed browser +yarn workspace @actual-app/web run playwright test --headed --debug accounts.test.ts +``` + +### E2E Test Structure + +- Tests are located in `packages/desktop-client/e2e/` +- Page models are in `e2e/page-models/` for reusable page interactions +- Mobile tests have `.mobile.test.ts` suffix + +## Visual Regression Tests (VRT) + +Visual regression tests capture screenshots and compare them to baseline images to detect visual changes. + +```bash +# Run visual regression tests +yarn vrt + +# Run visual regression tests in Docker (consistent environment) +yarn vrt:docker +``` + +Visual regression snapshots are stored per test file in `*-snapshots/` directories. Use Docker for consistent environments when running VRT. They will be automatically generated and run on pull requests to catch unexpected visual changes. + +## Debugging Test Failures + +### Lage Cache Issues + +If tests behave unexpectedly, the Lage cache might be causing issues: + +```bash +# Clear Lage cache +rm -rf .lage + +# Run tests without cache +yarn test:debug +``` + +### Tests Continue on Error + +With the `--continue` flag, all packages run even if one fails. This helps identify all test failures across the monorepo in a single run. + +### Debug Mode + +```bash +# Run tests in debug mode (without parallelization) +yarn test:debug + +# Run specific E2E test with headed browser and debug mode +yarn workspace @actual-app/web run playwright test --headed --debug accounts.test.ts +``` + +## Test Configuration + +### Vitest Configuration + +- Root config: `vitest.config.ts` (for node environment) +- Web config: `vitest.web.config.ts` (for browser environment) +- Sync-server tests have globals explicitly defined in config + +### Playwright Configuration + +- Config file: `packages/desktop-client/playwright.config.ts` +- Test reports: `packages/desktop-client/playwright-report/` +- Test results: `packages/desktop-client/test-results/` + +## Testing Checklist + +Before submitting a pull request: + +- [ ] All existing tests pass (`yarn test`) +- [ ] New functionality has appropriate test coverage +- [ ] Tests follow best practices (minimize mocking, descriptive names) +- [ ] E2E tests pass if UI changes were made + +## Additional Resources + +- [Vitest Documentation](https://vitest.dev/) +- [Playwright Documentation](https://playwright.dev/) +- [Lage Documentation](https://microsoft.github.io/lage/) diff --git a/packages/docs/docs/contributing/troubleshooting.md b/packages/docs/docs/contributing/troubleshooting.md new file mode 100644 index 0000000000..24f1d3f538 --- /dev/null +++ b/packages/docs/docs/contributing/troubleshooting.md @@ -0,0 +1,160 @@ +--- +title: Troubleshooting +--- + +This guide helps you resolve common issues when developing for Actual. + +## Type Errors + +### Issue: TypeScript compilation errors + +**Solution:** + +1. Run `yarn typecheck` to see all type errors +2. Check if types are imported correctly +3. Look for existing type definitions in `packages/loot-core/src/types/` +4. Use `satisfies` instead of `as` for type narrowing + +### Issue: Cannot find module or type definitions + +**Solution:** + +1. Check `tsconfig.json` for path mappings +2. Ensure you're using the correct import path for the package +3. Run `yarn install` to ensure all dependencies are installed + +## Linter Errors + +### Issue: ESLint or Prettier errors + +**Solution:** + +1. Run `yarn lint:fix` to auto-fix many issues +2. Check ESLint output for specific rule violations and fix them + +## Test Failures + +### Issue: Tests fail unexpectedly + +**Solution:** + +1. Check if test is running in correct environment (node vs web) +2. **Lage cache issues**: Clear cache with `rm -rf .lage` if tests behave unexpectedly + +### Issue: E2E tests fail + +**Solution:** + +1. Ensure Playwright browsers are installed: `yarn workspace @actual-app/web run playwright install` +2. Run tests with headed browser for debugging: `yarn workspace @actual-app/web run playwright test --headed --debug` + +## Import Resolution Issues + +### Issue: Platform-specific import errors + +**Solution:** + +- Don't directly reference platform-specific imports (`.api`, `.web`, `.electron`) +- Use conditional exports in `loot-core` for platform-specific code + +## Build Failures + +### Issue: Build fails with errors + +**Solution:** + +1. Clean build artifacts: + ```bash + rm -rf packages/*/dist packages/*/lib-dist packages/*/build + ``` +2. Reinstall dependencies: + ```bash + yarn install + ``` +3. Check Node.js version (requires >=22): + ```bash + node --version + ``` +4. Check Yarn version (requires ^4.9.1): + ```bash + yarn --version + ``` + +### Issue: Native module build failures (better-sqlite3) + +**Solution:** + +1. On Windows: Ensure you selected "Automatically install the necessary tools" during Node.js installation +2. Run `yarn rebuild-electron` for Electron builds +3. Run `yarn workspace loot-core rebuild` for Node.js builds +4. Ensure you have the necessary build tools installed (Python, Visual Studio Build Tools on Windows) + +## Development Server Issues + +### Issue: Development server won't start + +**Solution:** + +1. Check if port is already in use +2. Ensure all dependencies are installed: `yarn install` +3. Try clearing node_modules and reinstalling: + ```bash + rm -rf node_modules packages/**/node_modules + yarn install + ``` +4. Check for error messages in the console + +### Issue: Hot reload not working + +**Solution:** + +1. Ensure you're running the correct development command +2. Check if file watchers are working (may be limited on some systems) +3. Try restarting the development server +4. Check for file system permission issues + +## Workspace Command Issues + +### Issue: Workspace command not found + +**Solution:** + +1. Ensure you're running commands from the root directory +2. Verify workspace name is correct: `yarn workspaces list` +3. Check package.json for available scripts +4. Use correct workspace alias (e.g., `@actual-app/web` instead of `desktop-client`) + +## Git Issues + +### Issue: Pre-commit hooks failing + +**Solution:** + +1. Ensure Husky is set up: `yarn prepare` +2. Run linting manually: `yarn lint:fix` +3. Run type checking: `yarn typecheck` +4. Fix any errors before committing + +## Environment Issues + +### Issue: Wrong Node.js or Yarn version + +**Solution:** + +1. Check required versions in `package.json`: + - Node.js: >=22 + - Yarn: ^4.9.1 +2. Use a version manager: + - [nvm](https://github.com/nvm-sh/nvm) for Node.js + - Yarn version is managed by the `packageManager` field +3. Update your environment to match requirements + +## Getting Help + +If you're still experiencing issues: + +1. Check the [Development Setup Guide](./development-setup.md) for setup instructions +2. Review the [Testing Guide](./testing.md) for test-related issues +3. Check the [Code Style Guide](./code-style.md) for code-related issues +4. Ask for help in the [Discord community](https://discord.gg/pRYNYr4W5A) +5. Search or create an issue on [GitHub](https://github.com/actualbudget/actual/issues) diff --git a/packages/docs/docs/contributing/writing-docs.md b/packages/docs/docs/contributing/writing-docs.md index a7fb63673a..12668c8ff2 100644 --- a/packages/docs/docs/contributing/writing-docs.md +++ b/packages/docs/docs/contributing/writing-docs.md @@ -12,7 +12,7 @@ A better approach for inexperienced people, as it explains what each step is doi 1. Stop the server if it's running. You can use the keyboard shortcut (even on macOS) to stop the server or close the terminal window it's running from. 2. Run `git pull` from the directory you cloned the project into. This will download the latest server code. 3. Run `yarn install` from that same directory. This will download the latest web client code and any updated dependencies for the server. -4. Restart the server by running `yarn start`. +4. Restart the server by running `yarn start:docs` diff --git a/upcoming-release-notes/6120.md b/upcoming-release-notes/6120.md new file mode 100644 index 0000000000..4388e8c9e4 --- /dev/null +++ b/upcoming-release-notes/6120.md @@ -0,0 +1,7 @@ +--- +category: Maintenance +authors: [MatissJanis] +--- + +Agents.md: add missing information +