PR conventions
Base branch and merge strategy
Section titled “Base branch and merge strategy”- Base branch is
main. Fork the repo, work in afeature/*orbugfix/*branch, open a PR againstmain. - Squash-and-merge only (repo setting). Write your commits as if they’ll be squashed - the PR title and description are what land in
main.
Commit style
Section titled “Commit style”- Past tense, describes the change: “Added X”, “Fixed Y”, “Split A into B”.
- Do NOT use
feat:/chore:/fix:conventional-commit prefixes. They don’t match this repo’s history. - Do NOT hard-wrap commit-message bodies. A paragraph is one line, however long it needs to be. Only insert newlines between subject/body and between logical paragraphs.
- Do NOT use em dashes (
-) or en dashes (–). Use a plain ASCII hyphen (-) with spaces on both sides for a pause:-. - Do NOT mention test-pass counts. Green tests are the precondition for committing at all - noting “all N tests pass” is redundant.
- No Markdown formatting inside the commit message body (no
**bold**, no##headings, no bullet decorations).git logrenders commit messages verbatim.
Identifiers
Section titled “Identifiers”- Spell in full.
directorynotdir,configurationnotcfg. - Acronyms are uppercase in prose:
ID,URL,API,JSON. In code, follow the file’s existing casing convention. - Don’t repeat the object name in a field name. On
LoggerNotificationRecipient__c, the recipient’s user lookup isUser__c, notRecipientUser__c. - Boolean fields start with a verb -
IsEnabled__c,SupportsUser__c,HasError__c. Avoid bare adjectives likeRequired__c.
Naming: no Base in identifiers
Section titled “Naming: no Base in identifiers”Do not name files, classes, or components <Something>Base, <Something>BaseClass, or any variant containing the word Base. Name things after what they do, not their role in a composition or inheritance hierarchy.
SObjectType casing
Section titled “SObjectType casing”Write SObjectType (PascalCase) or sobjectType (camelCase). Never SobjectType (only leading S) and never sObjectType (capital O mid-word).
Product name
Section titled “Product name”The product is Nebula Logger. Always use the full name in prose - never shorten to “Nebula” alone.
DML routes through LoggerDataStore
Section titled “DML routes through LoggerDataStore”Never write raw insert x; / update x; / etc. in Nebula Logger Apex - main code and tests. Every DML and every System.enqueueJob(...) routes through LoggerDataStore.getDatabase().* or LoggerDataStore.getJobQueue().enqueueJob(...).
Testing
Section titled “Testing”Every code change ships with tests. See Testing.
- Apex:
Foo_Tests.clswithit_should_*methods. - LWC: colocated
__tests__/foo.test.jsusingsfdx-lwc-jest. - Jest tests validate the data sent to Apex methods (
toHaveBeenCalledWith), not just that they were called.
Before opening a PR
Section titled “Before opening a PR”npm run prettier:fix- format staged files.npm run scan- PMD + ESLint + SLDS.npm run test:apex:nocoverage(or fullnpm run test:apexif the change is bigger).npm run test:lwc:nocoverage(or fullnpm run test:lwc).- Update docs if you changed public API - see Docs generation below.
- Squash or amend as needed to keep the history clean.
Docs generation
Section titled “Docs generation”Public/global Apex and LWC APIs are documented via @cparra/apexdocs and jsdoc-to-markdown. If you change a public API:
npm run docs:fixThat runs the docs generation script. Commit the updated Markdown files under docs/src/content/docs/metadata-reference/.
Verify before pushing:
npm run docs:verifyPasses if the docs are already up-to-date. Fails and prints the diff if not.
AI contributor guide
Section titled “AI contributor guide”CLAUDE.md at the repo root contains conventions specifically for AI coding agents. If you’re working with Claude Code, Cursor, or a similar tool, that file is what they’ll load. Human contributors should skim it too - it’s a short-form companion to CONTRIBUTING.md.