Checkstack Documentation

Contributing to Checkstack

Thank you for your interest in contributing to Checkstack! This guide will help you get started with contributing plugins or code to the project.

Table of Contents

Getting Started

Prerequisites

Fork and Clone

# Fork the repository on GitHub
# Then clone your fork
git clone https://github.com/YOUR_USERNAME/checkstack.git
cd checkstack

Install Dependencies

bun install

Synchronize Configurations

Ensure your project follows the shared standards for TypeScript and package scripts:

bun run core/scripts/src/sync.ts

Set Up Database

# Create a PostgreSQL database
createdb checkstack_dev

# Set environment variables
cp .env.example .env
# Edit .env and set DATABASE_URL

Run Development Server

# Start backend and frontend
bun run dev

The application will be available at:

Development Setup

Project Structure

checkstack/
├── core/          # Core packages
│   ├── backend/      # Backend core
│   ├── frontend/     # Frontend core
│   ├── backend-api/  # Backend plugin API
│   ├── frontend-api/ # Frontend plugin API
│   ├── common/       # Shared types
│   ├── ui/           # UI components
│   ├── tsconfig/     # Shared TypeScript configurations
│   └── scripts/      # Shared monorepo scripts
│
├── plugins/          # Plugin packages
│   ├── catalog-backend/
│   ├── catalog-frontend/
│   ├── catalog-common/
│   └── ...
│
├── docs/             # Documentation
└── scripts/          # Build and utility scripts

Available Scripts

# Development
bun run dev              # Start dev servers
bun run dev:backend      # Backend only
bun run dev:frontend     # Frontend only

# Building
bun run build            # Build all packages
bun run build:backend    # Backend only
bun run build:frontend   # Frontend only

# Testing
bun test                 # Run all tests
bun test:watch           # Watch mode

# Tooling (Standardized via @checkstack/scripts)
bun run sync             # Synchronize project configurations
bun run lint             # Run all linters
bun run typecheck        # TypeScript type checking

# Database
bun run db:generate      # Generate migrations
bun run db:migrate       # Run migrations
bun run db:studio        # Open Drizzle Studio

Creating a Plugin

1. Choose Plugin Type

Decide what type of plugin you’re creating:

Most plugins will have all three.

2. Create Plugin Structure

# Create directories
mkdir -p plugins/myplugin-backend/src
mkdir -p plugins/myplugin-frontend/src
mkdir -p plugins/myplugin-common/src

3. Initialize Packages

Create package.json for each package. Then run the sync tool to apply shared configurations:

bun run sync

See:

4. Implement Plugin

Follow the guides above to implement your plugin.

5. Test Your Plugin

Write tests for your plugin:

# Unit tests
bun test plugins/myplugin-backend/src/**/*.test.ts

# Integration tests
bun test plugins/myplugin-backend/src/**/*.integration.test.ts

6. Document Your Plugin

Create a README in your plugin directory:

# My Plugin

## Description

What does this plugin do?

## Configuration

How to configure this plugin.

## Usage

How to use this plugin.

## API

API endpoints or components provided.

Code Style

TypeScript

Naming Conventions

Code Organization

// 1. Imports (grouped)
import { z } from "zod";
import { createBackendPlugin } from "@checkstack/backend-api";

// 2. Types and interfaces
interface MyData {
  id: string;
  name: string;
}

// 3. Constants
const DEFAULT_TIMEOUT = 5000;

// 4. Implementation
export class MyService {
  // ...
}

Comments

/**
 * Fetches items from the database.
 * @param filter - Optional filter criteria
 * @returns Array of items matching the filter
 */
async getItems(filter?: ItemFilter): Promise<Item[]> {
  // Use a transaction to ensure consistency
  return await db.transaction(async (tx) => {
    // ...
  });
}

Testing

Unit Tests

Test individual functions and classes:

import { describe, expect, test } from "bun:test";
import { MyService } from "./my-service";

describe("MyService", () => {
  test("creates item", async () => {
    const service = new MyService(mockDb);
    const item = await service.createItem({ name: "Test" });
    expect(item.name).toBe("Test");
  });
});

Integration Tests

Test plugin integration with the core:

import { describe, expect, test } from "bun:test";
import plugin from "./index";

describe("MyPlugin Integration", () => {
  test("registers correctly", () => {
    expect(plugin.pluginId).toBe("myplugin");
    expect(plugin.register).toBeFunction();
  });
});

E2E Tests (Frontend)

Use Playwright for end-to-end tests:

import { test, expect } from "@playwright/test";

test("user can create item", async ({ page }) => {
  await page.goto("/items");
  await page.click("text=Create Item");
  await page.fill("#name", "New Item");
  await page.click("text=Save");
  await expect(page.locator("text=New Item")).toBeVisible();
});

Test Coverage

Aim for:

Submitting Changes

1. Create a Branch

git checkout -b feature/my-new-plugin

Use prefixes:

2. Make Changes

bun run sync
bun run lint
bun run typecheck
bun test

3. Commit Changes

Use conventional commits:

git commit -m "feat(myplugin): add new feature"
git commit -m "fix(catalog): resolve bug in entity service"
git commit -m "docs: update plugin architecture guide"

Prefixes:

4. Push and Create PR

git push origin feature/my-new-plugin

Then create a Pull Request on GitHub.

PR Guidelines

Example PR description:

## Description

Adds a new HTTP health check plugin that supports custom headers and retry logic.

## Changes

- Created `healthcheck-http-backend` plugin
- Added support for custom headers
- Implemented retry logic with exponential backoff
- Added comprehensive tests

## Testing

- [x] Unit tests pass
- [x] Integration tests pass
- [x] Manual testing completed

## Screenshots

![Health check configuration](./assets/screenshots/config.png)

## Breaking Changes

None

Plugin Guidelines

Backend Plugins

Frontend Plugins

Common Plugins

Documentation

Architecture Rules

Dependency Rules

These are automatically enforced by the linter:

See dependency-linter.md for details.

Database Isolation

See drizzle-schema-isolation.md for details.

Versioned Configs

See versioned-configs.md for details.

Getting Help

Documentation

Community

Code Review

All contributions go through code review. Reviewers will check:

Be responsive to feedback and iterate on your PR.

License

By contributing to Checkstack, you agree that your contributions will be licensed under the same license as the project.

Thank You!

Thank you for contributing to Checkstack! Your contributions help make this project better for everyone.