Skip to main content

Code contribution guide

Cobblr's codebase is opinionated on purpose, and a contribution is reviewed as much for shape as for what it does. How the system is put together lives in Architecture; this page is the checklist your PR is read against. None of it is arbitrary; each rule exists because breaking it broke something once.

Respect the module shape

  • Never import another module. Compose through the platform contract only, and make sure your change works with any subset of modules enabled. A module that assumes Inventory exists is a bug, even if every workspace you've seen has Inventory.
  • Name it for what it is. A user-facing noun is a domain (bare name, opt-in); plumbing is a capability (core-<thing>, auto-enabled). "It's a core feature" is not what core- means: inventory is as first-party as it gets, and its name is bare. See the module system for the mechanics and the identifier pattern your kinds, events, actions, tables, and routes must follow.

Generic, never use-case-shaped

Cobblr's modules serve a workshop, a yarn stash, and a lego club with the same code, and that only holds if nothing is written for one of them:

  • Actions stay generic. No use case in an action's name or logic. The yarn flavor comes from skinning and bundles, not from a yarn: anything.
  • Behavior derives from declared fields, not from keyword lists. If a feature needs to know an entity is quantity-like, it reads the field's declared role, it doesn't match on names.
  • Native fields are universal-only. A kind's built-in fields are the small set every instance plausibly has. Give a column a generic, stable key and tune the default label instead of adding parallel fields: a car's VIN is its serial number, so relabel it, don't add a second identifier.

Upgrades must self-heal

A module owns its migrations, and an upgrade must bring existing data along automatically. Requiring a user to uninstall and reinstall, or to run a manual script, is a defect. Never destroy or reset user data to make a schema change easier.

UI conventions

  • Detail, edit, and destructive flows are modals; routine feedback is a toast. Never confirm() or alert().
  • Overlays render through a portal to body (the header's backdrop blur traps position: fixed elements).
  • Every backend capability gets real, clickable UI. If testing your feature required curl, the UI half isn't done.
  • Match the style around you: existing components, existing spacing, the workspace theme in both light and dark.

What "done" includes

  • Typecheck and the integration test suite pass; new behavior comes with tests.
  • User-visible flows get an end-to-end test that asserts, not just screenshots.
  • The user guide is updated in the same change when a feature changes what users see.
  • A changelog entry describes the change in user terms.

Process

The mechanics (DCO sign-off, how PRs are imported into the canonical repo, and the license) are on the main Contributing page. Small, focused PRs that state which rules above they touch get through review fastest.