Skip to content

Internal development guide

Gerege Nexus (gerege-systems/nexus-gerege-private, Go module github.com/gerege-systems/nexus-gerege-private/backend) is a private project. This guide is for the authorized development team.

Монгол  ·  English


Maintainers


Development workflow

1. Reporting bugs

Check the open issues first so you don't file a duplicate. A good report includes:

  • Clear steps to reproduce.
  • Your environment (Go version, Node.js version, OS, PostgreSQL version).
  • Expected versus actual behaviour, with logs where possible.

2. Suggesting enhancements

Describe the use case, the problem you are solving and the solution you have in mind.

3. Submitting pull requests

  1. Create a branch — git checkout -b feature/amazing-feature.
  2. Follow the code conventions:
  3. Backend: Go 1.26+, gofmt formatting, structured logging with slog, explicit error handling.
  4. Frontend: Next.js 16 App Router, TypeScript strict mode, Tailwind CSS.
  5. Write tests — new backend logic ships with *_test.go coverage.
  6. Run the verification suite:
# Backend: format, static analysis, tests
cd backend
gofmt -l .
go vet ./...
go test -race ./...
golangci-lint run

# Frontend: typecheck and build
cd ../frontend
npx tsc --noEmit
npm run build
  1. Commit messages follow Conventional Commits:
  2. feat: add invoice management module
  3. fix: resolve stock level calculation rounding
  4. docs: update module authoring guide
  5. Open the PR against main. Lint, tests, the frontend build and the security scans must all be green.

Adding a new business module

Business modules do not live in this repository but in a distribution repository — backend/internal/apps is the assembly point and is empty on purpose.

  1. In the distribution repository, create a package (modules/<module_name>/) that implements the nexus.Module interface from backend/pkg/nexus.
  2. Call nexus.Register(m) from its constructor; if it brings its own schema, also nexus.Migrations(id, fs) (it runs under its own public.goose_db_version_<slug> table). The distribution's main.go constructs its modules and calls host.Run.
  3. Add catalog/manifests/<slug>.json (it must match Manifest in pkg/catalog exactly — a malformed manifest stops the server from booting), catalog/chronicle/<slug>.json, and an entry in the distribution's catalog/apps.json. An installation refuses a module the binary carries but the catalogue does not name.
  4. Screens live in the core shell under frontend/app/module/<slug>/; register the app's dictionary from that route's layout.tsx (Translation).

Writing a module walks through this in detail, and Distribution describes the contract with the core.


Pull requests that touch backend/pkg/nexus

This package is the ecosystem's contract: every distribution repository compiles against it and pins it by tag. Therefore:

  • CODEOWNERS review is required (.github/CODEOWNERS).
  • If the exported surface changes, run go test ./pkg/nexus -update and include the testdata/api.txt diff in the PR. That diff tells the review exactly what the contract gained or lost.
  • A breaking change goes deprecation → one major cycle. The rules are in the "Хувилбарын амлалт" (versioning promise) section of Writing a module.

Theming a deployment

The whole UI is built on @gerege-systems/ui, and the single source of tokens is the library's theme.css. The legacy --gerege-* names are aliases of those tokens (frontend/app/globals.css). So every installation tunes its look on ui.gecore.mn/#theme and supplies only what Get code hands out:

  1. The <html> attributes it names → the BRAND_THEME_STYLE, BRAND_THEME_DEPTH, BRAND_THEME_RADIUS and BRAND_THEME_ACCENT environment variables.
  2. The printed :root / .dark block → a ./brand/theme.css file with BRAND_THEME_CSS_FILE=/brand/theme.css (or, for a line or two, inline in BRAND_THEME_CSS).

No core code changes; the block lands at the end of <body> and overrides both the library's and the core's tokens. The core's own look is written as exactly such a block (globals.css, the "Theme editor" section; style nexus, depth soft, Gerege blue). Only when a user picks an accent under Settings → Appearance is data-accent set, overriding the installation's colour in that browser; the "This deployment's" option returns to it.

BRAND_THEME_COLOR is separate from all of these: it is the hex colour of the PWA manifest and <meta name="theme-color"> (the browser toolbar, the installed app's window). It does not affect UI tokens, so give it a colour close to the accent. The full list for a distribution is in Distribution.


Documentation and translations

  • Mongolian is the primary language. Translations live under docs/ with the _AR, _EN, _ES, _FR, _RU and _ZH suffixes (the README in all six; DEVELOPMENT and SECURITY in _EN only). When the Mongolian source changes, translations must keep the same structure.
  • Do not use emoji in documentation. Where an icon is needed, use the Flaticon assets in assets/icons/ and add the source to ATTRIBUTION.md.
  • See README.md for how to add a new translation.