diff --git a/.gitignore b/.gitignore
index d45de5ca..8719d1d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
.DS_Store
.idea/
+.env
engine/bin/
/db-lab-run/
@@ -13,3 +14,5 @@ engine/bin/
/engine/configs/ci_checker.yml
engine/meta
+
+ui/packages/shared/dist/
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 00000000..2de3285e
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,148 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+
+## Architecture Overview
+### Core Components
+1. **Backend code** (`engine/`)
+ 1.1. **Entry Points** (`cmd/`)
+2. **Frontend code** (`ui/`)
+
+## Build/Test/Lint Commands
+- Build all components: `cd engine && make build`
+- Lint code: `cd engine && make lint`
+- Run unit tests: `cd engine && make test`
+- Run integration tests: `cd engine && make test-ci-integration`
+- Run a specific test: `cd engine && GO111MODULE=on go test -v ./path/to/package -run TestName`
+- Run UI: `cd ui && pnpm start:ce` (Community Edition) or `pnpm start:platform`
+
+## Code Style Guidelines
+- Go code follows "Effective Go" and "Go Code Review Comments" guidelines
+- Use present tense and imperative mood in commit messages
+- Limit first commit line to 72 characters
+- All Git commits must be signed
+- Format Go code with `cd engine && make fmt`
+- Use error handling with pkg/errors
+- Follow standard Go import ordering
+- Group similar functions together
+- Error messages should be descriptive and actionable
+- UI uses pnpm for package management
+
+## Important Backend Workflow Notes
+
+- Always run tests, linter and normalize comments BEFORE committing anything
+- Run formatting, code generation, linting and testing on completion
+- Never commit without running completion sequence
+- Run tests and linter after making significant changes to verify functionality
+- IMPORTANT: Never put into commit message any mention of Claude or Claude Code
+- IMPORTANT: Never include "Test plan" sections in PR descriptions
+- Do not add comments that describe changes, progress, or historical modifications
+- Comments should only describe the current state and purpose of the code, not its history or evolution
+- After important functionality added, update README.md accordingly
+- When merging master changes to an active branch, make sure both branches are pulled and up to date first
+- Don't leave commented out code in place
+- Avoid multi-level nesting
+- Avoid multi-level ifs, never use else if
+- Never use goto
+- Avoid else branches if possible
+- Write tests in compact form by fitting struct fields to a single line (up to 130 characters)
+- Before any significant refactoring, ensure all tests pass and consider creating a new branch
+- When refactoring, editing, or fixing failed tests:
+ - Do not redesign fundamental parts of the code architecture
+ - If unable to fix an issue with the current approach, report the problem and ask for guidance
+ - Focus on minimal changes to address the specific issue at hand
+ - Preserve the existing patterns and conventions of the codebase
+
+## Backend Code Style Guidelines
+
+### Import Organization
+- Organize imports in the following order:
+ 1. Standard library packages first (e.g., "fmt", "context")
+ 2. A blank line separator
+ 3. Third-party packages
+ 4. A blank line separator
+ 5. Project imports (e.g., "gitlab.com/postgres-ai/database-lab/v3/pkg/*")
+- Example:
+ ```go
+ import (
+ "context"
+ "fmt"
+ "net/http"
+
+ "github.com/docker/docker/api/types"
+ "github.com/gorilla/mux"
+
+ "gitlab.com/postgres-ai/database-lab/v3/pkg/util/branching"
+ )
+ ```
+
+### Error Handling
+- Return errors to the caller rather than using panics
+- Use descriptive error messages that help with debugging
+- Use error wrapping: `fmt.Errorf("failed to process request: %w", err)`
+- Check errors immediately after function calls
+- Return early when possible to avoid deep nesting
+
+### Variable Naming
+- Use descriptive camelCase names for variables and functions
+- Good: `notFoundHandler`, `requestContext`, `userID`
+- Bad: `not_found_handler`, `x`, `temp1`
+- Be consistent with abbreviations (e.g., `httpClient` not `HTTPClient`)
+- Local scope variables can be short (e.g., "lmt" instead of "orderLimit")
+- Use constants for magic numbers and strings
+- Use meaningful names for constants and enums
+
+### Function Parameters
+- Group related parameters together logically
+- Use descriptive parameter names that indicate their purpose
+- Consider using parameter structs for functions with many (4+) parameters
+- If function returns 3 or more results, consider wrapping in Result/Response struct
+- If function accepts 3 or more input parameters, consider wrapping in Request/Input struct (but never add context to struct)
+
+### Documentation
+- All exported functions, types, and methods must have clear godoc comments
+- Begin comments with the name of the element being documented
+- Include usage examples for complex functions
+- Document any non-obvious behavior or edge cases
+- All comments should be lowercase, except for godoc public functions and methods
+- IMPORTANT: all comments except godoc comments must be lowercase, test messages must be lowercase, log messages must be lowercase
+
+### Code Structure
+- Keep code modular with focused responsibilities
+- Limit file sizes to 300-500 lines when possible
+- Group related functionality in the same package
+- Use interfaces to define behavior and enable mocking for tests
+- Keep code minimal and avoid unnecessary complexity
+- Don't keep old functions for imaginary compatibility
+- Interfaces should be defined on the consumer side (idiomatic Go)
+- Aim to pass interfaces but return concrete types when possible
+- Consider nested functions when they simplify complex functions
+
+### Code Layout
+- Keep cyclomatic complexity under 30
+- Function size preferences:
+ - Aim for functions around 50-60 lines when possible
+ - Don't break down functions too small as it can reduce readability
+ - Maintain focus on a single responsibility per function
+- Keep lines under 130 characters when possible
+- Avoid if-else chains and nested conditionals:
+ - Never use long if-else-if chains; use switch statements instead
+ - Prefer early returns to reduce nesting depth
+ - Extract complex conditions into separate boolean functions or variables
+ - Use context structs or functional options instead of multiple boolean flags
+
+### Testing
+- Write thorough tests with descriptive names (e.g., `TestRouter_HandlesMiddlewareCorrectly`)
+- Prefer subtests or table-based tests, using Testify
+- Use table-driven tests for testing multiple cases with the same logic
+- Test both success and error scenarios
+- Mock external dependencies to ensure unit tests are isolated and fast
+- Aim for at least 80% code coverage
+- Keep tests compact but readable
+- If test has too many subtests, consider splitting it to multiple tests
+- Never disable tests without a good reason and approval
+- Important: Never update code with special conditions to just pass tests
+- Don't create new test files if one already exists matching the source file name
+- Add new tests to existing test files following the same naming and structuring conventions
+- Don't add comments before subtests, t.Run("description") already communicates what test case is doing
+- Never use godoc-style comments for test functions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f32b4abf..4d399f35 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -23,11 +23,11 @@ These are mostly guidelines, not rules. Use your best judgment, and feel free to
- [Git commit messages](#git-commit-messages)
- [Go styleguide](#go-styleguide)
- [Documentation styleguide](#documentation-styleguide)
+ - [API design and testing](#api-design-and-testing)
+ - [UI development](#ui-development)
- [Development setup](#development-setup)
- [Repo overview](#repo-overview)
-
---
@@ -121,6 +121,45 @@ We encourage you to follow the principles described in the following documents:
- [Effective Go](https://go.dev/doc/effective_go)
- [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments)
+### Message style guide
+Consistent messaging is important throughout the codebase. Follow these guidelines for errors, logs, and user-facing messages:
+
+#### Error messages
+- Lowercase for internal errors and logs: `failed to start session` (no ending period)
+- Uppercase for user-facing errors: `Requested object does not exist. Specify your request.` (with ending period)
+- Omit articles ("a", "an", "the") for brevity: use `failed to update clone` not `failed to update the clone`
+- Be specific and actionable whenever possible
+- For variable interpolation, use consistent formatting: `failed to find clone: %s`
+
+#### CLI output
+- Use concise, action-oriented language
+- Present tense with ellipsis for in-progress actions: `Creating clone...`
+ - Ellipsis (`...`) indicates an ongoing process where the user should wait
+ - Always follow up with a completion message when the operation finishes
+- Past tense with period for results: `Clone created successfully.`
+- Include relevant identifiers (IDs, names) in output
+
+#### Progress indication
+- Use ellipsis (`...`) to indicate that an operation is in progress and the user should wait
+- For longer operations, consider providing percentage or step indicators: `Cloning database... (25%)`
+- When an operation with ellipsis completes, always provide a completion message without ellipsis
+- Example sequence:
+ ```
+ Creating clone...
+ Clone "test-clone" created successfully.
+ ```
+
+#### UI messages
+- Be consistent with terminology across UI and documentation
+- For confirmations, use format: `{Resource} {action} successfully.`
+- For errors, provide clear next steps when possible
+- Use sentence case for all messages (capitalize first word only)
+
+#### Commit messages
+- Start with lowercase type prefix: `fix:`, `feat:`, `docs:`, etc.
+- Use imperative mood: `add feature` not `added feature`
+- Provide context in the body if needed
+
### Documentation styleguide
Documentation for Database Lab Engine and additional components is hosted at https://postgres.ai/docs and is maintained in this GitLab repo: https://gitlab.com/postgres-ai/docs.
@@ -132,6 +171,94 @@ We're building documentation following the principles described at https://docum
Learn more: https://documentation.divio.com/.
+### API design and testing
+The DBLab API follows RESTful principles with these key guidelines:
+- Clear resource-based URL structure
+- Consistent usage of HTTP methods (GET, POST, DELETE, etc.)
+- Standardized error responses
+- Authentication via API tokens
+- JSON for request and response bodies
+- Comprehensive documentation with examples
+
+#### API Documentation
+We use readme.io to host the API docs: https://dblab.readme.io/ and https://api.dblab.dev.
+
+When updating the API specification:
+1. Make changes to the OpenAPI spec file in `engine/api/swagger-spec/`
+2. Upload it to readme.io as a new documentation version
+3. Review and publish the new version
+
+#### Testing with Postman and Newman
+Postman collection is generated based on the OpenAPI spec file, using [Portman](https://github.com/apideck-libraries/portman).
+
+##### Setup and Generation
+1. Install Portman: `npm install -g @apideck/portman`
+2. Generate Postman collection file:
+ ```
+ portman --cliOptionsFile engine/api/postman/portman-cli.json
+ ```
+
+##### Test Structure Best Practices
+- Arrange tests in logical flows (create, read, update, delete)
+- Use environment variables to store and pass data between requests
+- For object creation tests, capture the ID in the response to use in subsequent requests
+- Add validation tests for response status, body structure, and expected values
+- Clean up created resources at the end of test flows
+
+##### CI/CD Integration
+The Postman collection is automatically run in CI/CD pipelines using Newman. For local testing:
+```
+newman run engine/api/postman/dblab_api.postman_collection.json -e engine/api/postman/branching.aws.postgres.ai.postman_environment.json
+```
+
+### UI development
+The Database Lab Engine UI contains two main packages:
+- `@postgres.ai/platform` - Platform version of UI
+- `@postgres.ai/ce` - Community Edition version of UI
+- `@postgres.ai/shared` - Common modules shared between packages
+
+#### Working with UI packages
+At the repository root:
+- `pnpm install` - Install all dependencies
+- `npm run build -ws` - Build all packages
+- `npm run start -w @postgres.ai/platform` - Run Platform UI in dev mode
+- `npm run start -w @postgres.ai/ce` - Run Community Edition UI in dev mode
+
+_Note: Don't use commands for `@postgres.ai/shared` - it's a dependent package that can't be run or built directly_
+
+#### Platform UI Development
+1. Set up environment variables:
+ ```bash
+ cd ui/packages/platform
+ cp .env_example_dev .env
+ ```
+2. Edit `.env` to set:
+ - `REACT_APP_API_URL_PREFIX` to point to dev API server
+ - `REACT_APP_TOKEN_DEBUG` to set your JWT token
+3. Start development server: `pnpm run start`
+
+#### CI pipelines for UI code
+To deploy UI changes, tag the commit with `ui/` prefix and push it:
+```shell
+git tag ui/1.0.12
+git push origin ui/1.0.12
+```
+
+#### Handling Vulnerabilities
+When addressing vulnerabilities in UI packages:
+1. Update the affected package to a newer version if available
+2. For sub-package vulnerabilities, try using [npm-force-resolutions](https://www.npmjs.com/package/npm-force-resolutions)
+3. As a last resort, consider forking the package locally
+
+For code-related issues:
+1. Consider rewriting JavaScript code in TypeScript
+2. Follow recommendations from security analysis tools
+3. Only ignore false positives when absolutely necessary
+
+#### TypeScript Migration
+- `@postgres.ai/shared` and `@postgres.ai/ce` are written in TypeScript
+- `@postgres.ai/platform` is partially written in TypeScript with ongoing migration efforts
+
### Repo overview
The [postgres-ai/database-lab](https://gitlab.com/postgres-ai/database-lab) repo contains 2 components:
- [Database Lab Engine](https://gitlab.com/postgres-ai/database-lab/-/tree/master/engine)
@@ -140,7 +267,6 @@ The [postgres-ai/database-lab](https://gitlab.com/postgres-ai/database-lab) repo
- [Database Lab CLI](https://gitlab.com/postgres-ai/database-lab/-/tree/master/engine/cmd/cli)
- [Database Lab UI](https://gitlab.com/postgres-ai/database-lab/-/tree/master/ui)
- [Community Edition](https://gitlab.com/postgres-ai/database-lab/-/tree/master/ui/packages/ce)
- - [Platform](https://gitlab.com/postgres-ai/database-lab/-/tree/master/ui/packages/platform)
- [Shared components](https://gitlab.com/postgres-ai/database-lab/-/tree/master/ui/packages/shared)
Components have a separate version, denoted by either:
@@ -191,10 +317,27 @@ Components have a separate version, denoted by either:
### Building from source
-Use `Makefile` to build Database Lab components from source.
+The Database Lab Engine provides multiple build targets in its `Makefile`:
+
+```bash
+cd engine
+make help # View all available build targets
+make build # Build all components (Server, CLI, CI Checker)
+make build-dle # Build Database Lab Engine binary and Docker image
+make test # Run unit tests
+```
+
+You can also build specific components:
+
+```bash
+# Build the CLI for all supported platforms
+make build-client
+
+# Build the Server in debug mode
+make build-debug
-Run `make help` to see all available targets.
+# Build and run DLE locally
+make run-dle
+```
-
+See our [GitLab Container Registry](https://gitlab.com/postgres-ai/database-lab/container_registry) to find pre-built images for development branches.
diff --git a/LICENSE b/LICENSE
index cb43d4eb..b0cc8d52 100644
--- a/LICENSE
+++ b/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright 2023 Postgres.ai https://postgres.ai/
+ Copyright 2023-2025 Postgres AI https://postgres.ai/
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/README.md b/README.md
index 03f77d9e..9eada025 100644
--- a/README.md
+++ b/README.md
@@ -8,18 +8,18 @@
+ ⚡ Blazing-fast PostgreSQL cloning and branching 🐘
🛠️ Build powerful dev/test environments.
🔃 Cover 100% of DB migrations with CI tests.
💡 Quickly verify ChatGPT ideas to get rid of hallucinations.
- Available for any PostgreSQL, including self-managed and managed* like AWS RDS, GCP CloudSQL, Supabase, Timescale.
- Can be installed and used anywhere: all clouds and on-premises.
+ Available for any PostgreSQL, including self-managed and managed services* like AWS RDS, GCP Cloud SQL, Supabase, and Timescale.
+ It can be installed and used anywhere: across all cloud environments and on-premises.
@@ -60,11 +60,11 @@ For example, cloning a 1 TiB PostgreSQL database takes just about 10 seconds. On