Skip to content

Latest commit

 

History

History
134 lines (105 loc) · 6.81 KB

CONTRIBUTING.md

File metadata and controls

134 lines (105 loc) · 6.81 KB

Contributing to Fulla

Thanks for your interest in contributing! This document covers the local workflow, conventions, and CI gates a change must pass.

By participating in this project you agree to uphold its Code of Conduct. Not sure where to ask something? See SUPPORT.md for the right channel.

Prerequisites

Tool Version
C++ compiler C++17 (MSVC 2022 / GCC 9+ / Clang 10+)
CMake 3.21+
Conan 2.x
Node.js 18+ (frontends only)
PostgreSQL / Redis 14+ / 7+ (optional — see memory-only tests below)

Build & Test

The canonical build is Conan 2 + CMake presets — the same flow CI runs:

conan install . --output-folder=build/linux-release --build=missing \
  -s build_type=Release -s compiler.cppstd=17
cmake --preset linux-release          # or windows-msvc / macos-arm64
cmake --build --preset linux-release
ctest --test-dir build/linux-release --output-on-failure

Useful variants:

  • No external DB: configure with -DFULLA_MEMORY_TESTS_ONLY=ON to run the suite against the in-memory storage backend (what Windows CI does).
  • Debug / sanitizers: use the -debug, -asan, -tsan preset variants (sanitizers are Linux/macOS only).
  • By category: ctest -R Unit|Integration|E2E|Security|Performance (labels are defined in tests/common/test_categories.h).
  • manage.ps1 / manage.sh wrap the same flow as convenience commands.

Frontends:

cd frontends/admin && npm install && npm run dev   # or frontends/user
npx playwright test                                # E2E

Code Conventions

  • Async style: repository/service methods take std::function<void(result)> &&callback as the last parameter. Async continuations must capture auto self = shared_from_this() — never [this] or [&]. Never use CoroMapper.
  • ORM models (libs/storage-postgres/src/models/**) are generated by drogon_ctl — never hand-edit them; regenerate via the ORM scripts in scripts/backend/.
  • DB access goes through the async Mapper + Criteria combo; raw SQL is reserved for DDL, UPDATE ... RETURNING, and documented batch operations.
  • Errors are stable string codes (e.g. AUTH_INVALID_CREDENTIALS) registered in the ErrorCatalog — never bare integers.
  • Architecture: Domain-layer packages (libs/common, libs/oauth2, libs/identity) must not include Drogon headers. tools/arch-guard enforces this in CI.
  • No emoji in code or program output (use [+] / [-] / [!]).

Logging

Six log levels mirror Drogon/Trantor (trace < debug < info < warn < error < fatal). Full definitions and typical use cases are in docs/operate/observability.md §3.2. Quick guide:

Level When to use
trace Function args/return values, SQL strings, per-iteration detail — deep debugging only
debug Variable values, branch decisions, internal-state dumps — dev troubleshooting
info Startup/shutdown, login, task completion, key flow checkpoints, audit-worthy normal events
warn Recoverable failure, degraded-but-working path, default value used, resource near threshold
error Single operation/request failed (DB error callback, unhandled exception), service still up
fatal Service cannot continue (startup config/migration failure) — must be rare

Rules:

  • Domain layer must log through the ILogger port (fulla::common::ports::ILogger), not Drogon's LOG_* macros, so tests can assert on output via FakeLogger. The adapter/infra layers (libs/drogon, libs/storage-*, apps/server) may use LOG_* directly. LogLevel::Trace routes to LOG_TRACE.
  • Pick the level by impact, not verbosity: a caught exception that still succeeds is warn, not error; a routine cache-miss or 401 is usually debug/info, not warn. When an operation fails outright with no fallback, use error.
  • Production runs at info by default; trace/debug are enabled on demand. Adjust via app.log.log_level in the Drogon config (values: TRACE/DEBUG/INFO/WARN/ERROR/FATAL).
  • Test output is minimal by default: ctest prints only failed tests' logs plus the pass/fail/total summary. Add --verbose (-V) to see every test, or -Q (manage.sh test-backend -q) for summary only.

Known audit residue: a handful of call sites remain at a level that's a policy judgement rather than a clear-cut bug (e.g. the [METRIC] log-based metric emissions at info, routine 401/403 denials at warn). These are intentionally left for a deliberate follow-up decision; when you touch such a site, consider whether its level matches the table above.

Commit & PR Conventions

  • Commits follow Conventional Commits: feat:, fix:, docs:, test:, build:, ci:, refactor: (scopes welcome, e.g. feat(auth): ...). Release notes are generated from them.
  • Branch names: feat/<topic>, fix/<topic>, docs/<topic>.
  • Target branch is master; every PR must pass all CI checks before merge.
  • CHANGELOG.md entries are written in English only — the changelog feeds the GitHub release notes verbatim (curated breaking-change entries are spliced into them), so it must stay single-language.

Documentation changes are bilingual (same-PR dual write)

The docs are bilingual: docs/ is the English canonical and website/i18n/zh-CN/docusaurus-plugin-content-docs/current/ is the Chinese mirror (identical layout/URLs; both feed fulla.dev). A PR that changes a document under docs/ must update its Chinese counterpart in the same PR (and vice versa). Full rules: docs/documentation-governance.md §4.

CI Gates

A PR runs ci.yml + security.yml:

Gate What it checks
Static Checks arch-guard layering, migration hygiene, api-diff (public SDK headers follow SemVer), test naming, manage.sh/manage.ps1 parity, OpenAPI validity
Build & Test Linux (GCC + PostgreSQL + Redis), Windows (MSVC, memory storage), macOS (Clang ARM64)
SDK Smoke examples/full-stack-host consumed via real find_package
Frontend Vitest property tests
Security secret & sensitive-file hygiene, dependency EOL check

If you change public SDK headers (include/fulla/**) intentionally, update tools/api-diff/api-baseline.txt in the same PR and call it out in the description — breaking changes require a major version bump.

Reporting Issues

  • Usage questions / discussions: GitHub Discussions (see SUPPORT.md for the full routing table).
  • Bugs / features: open a GitHub issue with reproduction steps.
  • Security vulnerabilities: do not open a public issue — see SECURITY.md.