Developer Guide
Consistent naming lets a reader infer an artefact’s role from its name alone. CrowdVision spans several languages and layers, so the conventions are defined per layer below. They are enforced partly by ESLint and partly by review; treat them as mandatory.
Every Node service follows the same internal layout, so the file you want is always in the same place.
| Path | Holds |
|---|---|
src/router.ts | Route declarations. |
src/controller/ | HTTP adapters (one file per concern). |
src/services/ | Business logic. |
src/models/ | Schemas and shared types. |
src/middlewares/ | Cross-cutting middleware. |
src/config/ | Environment accessors and client setup. |
__tests__/ | The service’s test suite. |
| Artefact | Convention | Recommended | Avoid |
|---|---|---|---|
| Controller / service files | camelCase, layer as suffix where it adds clarity | buildings.ts, notificationService.ts | twin_ctrl.ts, Notification.ts |
| Model files | camelCase file name | account.ts, buildingThreshold.ts | Account.ts, building_threshold.ts |
| Exported model and interface | PascalCase; interfaces prefixed I | export interface IAccount, export const Account = model(...) | export const account, export interface Account |
| Functions and variables | camelCase | generateStandardToken, allowedColumns | GenerateToken, allowed_columns |
| Constants | UPPER_SNAKE_CASE | ROLE_WEIGHTS, COOKIE_NAME | roleWeights |
| Database collections | plural, lowercase | accounts, buildings | Account, building |
| Artefact | Convention | Recommended | Avoid |
|---|---|---|---|
| Components | PascalCase, multi-word (to avoid clashing with HTML elements), file and tag | BuildingCard.vue, NotificationDropdown.vue, LeftMenu.vue | card.vue, header.vue |
| Views / pages (top-level routes) | PascalCase with a View suffix | DashboardView.vue, AdministrationView.vue | Dashboard.vue |
| Composables | camelCase, prefixed use | useBuildingModel.ts, useAuth.ts, useSceneControls.ts | buildingModel.ts, getAuth.ts |
| Utilities / helpers | camelCase | metrics.ts, formatTimestamp.ts | Metrics.ts |
Both Rust services follow idiomatic Rust style.
| Artefact | Convention | Example |
|---|---|---|
| Modules and files | snake_case | tunnel.rs, discovery.rs |
| Functions | snake_case | start_telemetry_tunnel, metric_is_allowed |
| Types (structs, enums) | PascalCase | AppState, PreferenceDocument |
| Constants | SCREAMING_SNAKE_CASE | RAW_CHANNEL, DEFAULT_COLUMNS |
claims-gateway, tenancy-service, registry-service, and provisioner follow idiomatic Go style (gofmt, checked by go vet in just lint).
| Artefact | Convention | Example |
|---|---|---|
| Packages and files | snake_case or single lowercase word, matching the package name | internal/api/handler.go, internal/store/ |
| Exported functions and types | PascalCase | func Mount(...), type Config struct |
| Unexported functions, types, and variables | camelCase (Go’s own export rule: capitalisation is visibility, not a separate style choice) | func writeDomain(...), type handler struct, func isValidAccountID(...) |
| Constants | PascalCase or camelCase per Go convention (no SCREAMING_SNAKE_CASE — that’s not idiomatic Go) | as appropriate to exported/unexported |
Package layout follows the standard Go project layout: internal/api (HTTP handlers), internal/service (business logic), internal/store (persistence, often with a storefake sibling for tests), internal/events (Redis Stream consumers/producers), internal/config.
The agent-service follows PEP 8: snake_case for modules, functions, and variables; PascalCase for classes; SCREAMING_SNAKE_CASE for constants. (The agent is maintained separately; these conventions are listed for completeness.)
Branch names mirror the commit types, so the branch announces its intent.
<type>/<short-kebab-description>| Type | Example |
|---|---|
feat | feat/private-domains |
fix | fix/jwt-expiry-off-by-one |
chore | chore/bump-dependencies |
docs | docs/sensor-api-reference |
refactor | refactor/extract-token-service |
Conventional-commit scopes use the service or area name, so history can be filtered by component.
feat(twin): add per-room colour overrides
fix(gateway): reject expired refresh tokens
docs(sensor): document the ingestion fast path
chore(ci): pin the kubeconform versionCommon scopes: gateway (claims-gateway), tenancy, registry, provisioner, twin, sensor, notification, socket, contracts, client, agent, ci, docs, k8s. The full commit format is covered in Commits & Release Please.
| Artefact | Convention | Example |
|---|---|---|
| Environment variables | UPPER_SNAKE_CASE | GATEWAY_ISSUER, SENSOR_SERVICE_URL |
| Docker images | crowdvision-<service> under the org namespace | ghcr.io/nickghignatti/crowdvision-twin |
| Workflow files | <category>-<name>.yml (ci-, cd-, maint-) | ci-twin.yml, cd-release.yml, maint-cleanup.yml |
| Documentation pages | kebab-case .qd | building-data.qd, naming-conventions.qd |