Source:
ocean/docs/adr/ADR-036-unified-field-naming-convention.md| ✏️ Edit on GitHub
ADR-036: Unified Field Naming Convention
Status
Proposed
Context
The Ocean platform currently has inconsistent field naming between layers:
- Database: snake_case (e.g.,
stripe_customer_id,member_role) - GraphQL API: camelCase (e.g.,
stripeCustomerId,memberRole) - Frontend: Mixed usage with transformation functions
This inconsistency leads to:
- Complex transformation logic in multiple places
- Increased cognitive load for developers
- Potential bugs from incorrect field mapping
- Duplicated type definitions
Decision
We will adopt a snake_case-first approach throughout the entire stack:
- Database: Continue using snake_case (PostgreSQL convention)
- GraphQL API: Use snake_case for all fields
- Frontend: Use snake_case directly from API responses
- Generated Types: Single source of truth from database schema
Implementation Strategy
- Update GraphQL schema to use snake_case fields
- Remove all transformation functions
- Update frontend to use snake_case consistently
- Regenerate GraphQL types with snake_case
Consequences
Positive
- Single naming convention across all layers
- No transformation logic needed
- Simpler type definitions
- Direct mapping from database to frontend
- Reduced code complexity
Negative
- Breaking change for existing API consumers (mitigated by being pre-launch)
- Goes against GraphQL convention of camelCase
- May look unusual in JavaScript/TypeScript code
Mitigation
- Since we're pre-launch, breaking changes are acceptable
- Modern TypeScript handles snake_case well
- ESLint rules can be adjusted to allow snake_case
Implementation Plan
- Update GraphQL schema.ts to use snake_case
- Update resolvers to return fields directly without transformation
- Remove transformation functions from hooks
- Update frontend components to use snake_case fields
- Regenerate all types