Skip to main content

Contributing Guide

First off, thank you for considering contributing to Citadel! We welcome any help, from reporting a bug to submitting a feature. This document provides guidelines to help you get started.

Core Development Principles (AI-Assisted Workflow)

This project is developed with the assistance of an AI coding partner. The following rules are the most important directives for any contributor, human or AI, and must be followed strictly.

1. One Change at a Time

All work must be performed in small, incremental steps. Each response from the AI assistant must propose only a single, focused file change. This includes creating a new file, modifying an existing file, or deleting a file. Do not bundle multiple changes into one response.

2. Test-Driven Development (TDD) is Mandatory

No feature or business logic should be implemented without a corresponding test being written first.

  • Start with a Failing Test: For any new functionality, the first step is always to write a test (unit, integration, or BDD scenario) that describes the desired behavior and is expected to fail.
  • Write Code to Pass the Test: The next step is to write the minimum amount of implementation code required to make the failing test pass.
  • Refactor: Once the test is passing, refactor the code for clarity and quality.

3. User-Directed Workflow

  • Suggest, Don't Act: The AI assistant's role is to suggest the next logical step (e.g., "The next step is to create the test file x.") and describe the extent of the change. It must not generate the code for that change until asked.
  • Wait for Confirmation: The AI must wait for the user to confirm the next step before proceeding. The user may choose a different path.

Code of Conduct

This project and everyone participating in it is governed by a Code of Conduct. By participating, you are expected to uphold this code. (A formal CODE_OF_CONDUCT.md will be added soon).

How to Contribute

We use the standard "Fork & Pull/Merge Request" model.

  1. Find an issue: Look through the existing issues to find something to work on. If you have a new idea, please open an issue first to discuss it with the maintainers.

  2. Fork the repository: Create a fork of the project to your own account.

  3. Create a branch: Create a new branch in your fork for your changes. Use a descriptive name, like feature/add-new-report or fix/resolve-bug-123.

    git checkout -b feature/my-new-feature
  4. Make your changes: Write your code and, most importantly, your tests!

  5. Submit a Pull/Merge Request: Push your branch to your fork and open a request to the main branch of the original repository.

Development Setup

Before you start coding, please follow the Getting Started Guide to set up your local development environment.

Development Workflow

We follow a Behavior-Driven Development (BDD) approach, which is a form of Test-Driven Development (TDD). This means that new features should ideally start with a test that describes the desired behavior.

Creating a New Frontend Application

All new frontend applications must be created using the provided scaffolding script to ensure they adhere to our architectural standards.

# Run from the root of the monorepo
./scripts/scaffold-ng-app.sh <your-app-name>

This script sets up an Angular application with the feature-sliced layout defined in ADR 0003.

It also makes a key architectural choice: it uses the standard zone.js-based change detection. For the full rationale behind this decision, please see ADR 0004.

Code Style & Formatting

We enforce a consistent code style across the monorepo using a combination of tools, orchestrated by pre-commit hooks.

  • Backend (Go, Python): A root .pre-commit-config.yaml defines hooks for tools like gofmt, ruff, black, and isort.
  • Frontend (TypeScript): Workspaces use a shared ESLint and Prettier configuration to ensure consistent rules for all JavaScript/TypeScript code.

Before you commit for the first time, please install the hooks from the root of the repository:

pre-commit install

Now, pre-commit will run automatically on every git commit to format your code and check for issues. If it makes changes, you will need to git add the modified files and commit again.

Running Tests

We use Turborepo to orchestrate testing across the entire monorepo. This allows you to run all tests, or only tests for affected applications, with a single command from the project root.

Running All Tests

To run the test suites for all applications and packages:

From the root of the monorepo

pnpm run test

Running Tests for a Specific Application

You can also run tests for a single application (e.g., iam-service):

From the root of the monorepo

pnpm run test --filter=iam-service

Turborepo intelligently invokes the correct, language-specific test runner for each application:

  • Go: go test ./...
  • Python: uv run pytest and uv run behave
  • TypeScript: jest or vitest

For detailed test coverage analysis, please refer to the reports generated by our CI/CD pipeline after a merge request is submitted.

Commit Messages

We follow the Conventional Commits specification. This helps us automate changelogs and makes the commit history more readable. Each commit message should be in the format:

<type>[optional scope]: <description>

[optional body]

[optional footer]

Example:

feat(reporting): add balance sheet report API

This commit introduces a new projector and API endpoint
for generating a balance sheet report. It subscribes
to JournalEntryPosted events to update balances.

Fixes #42

Common types include: feat, fix, docs, style, refactor, test, chore, ci.

Submitting Your Changes

When you are ready, push your branch to your fork and open a Pull/Merge Request.

  • Provide a clear title and description for your changes.
  • Link to the issue you are resolving.
  • Ensure that all CI checks are passing.

A maintainer will review your contribution and provide feedback. Thank you for your help!