Files
remotion_service/.claude/rules/coding-style.md
T
2026-04-06 01:44:58 +03:00

2.2 KiB

Coding Style (Extended)

Extends the style guidelines in CLAUDE.md with patterns from ECC.

Immutability

Create new objects — never mutate existing ones:

// WRONG: mutation
user.name = newName;
items.push(newItem);

// RIGHT: immutable update
const updated = { ...user, name: newName };
const updatedItems = [...items, newItem];
# WRONG: mutation
user["name"] = new_name
items.append(new_item)

# RIGHT: immutable (when it matters)
updated = {**user, "name": new_name}
updated_items = [*items, new_item]

Exception: Pydantic models and SQLAlchemy ORM objects are designed for mutation — use them as intended.

File Organization

  • 200-400 lines typical, 800 max per file
  • High cohesion, low coupling — one concept per file
  • Backend: module structure is fixed (models, schemas, repository, service, router) — don't add extra files
  • Frontend: FSD layers are fixed — don't add files outside the layer structure

Error Handling

Frontend

  • API errors: handle in TanStack Query onError callbacks or error boundaries
  • Form validation: react-hook-form with inline register() validation rules and Controller for controlled components. Error messages in Russian.
  • Never show raw error strings to users — map to user-friendly Russian messages

Backend

  • Raise HTTPException with appropriate status codes in routers
  • Service layer returns data or raises domain exceptions
  • Repository layer lets SQLAlchemy exceptions propagate (service handles them)
  • Store error messages as named constants with ERROR_ prefix

Input Validation

  • Frontend: TypeScript interfaces + react-hook-form inline rules for form data, OpenAPI-generated types for API responses
  • Backend: Pydantic schemas validate all request bodies — never trust raw input
  • File uploads: validate extension + MIME type in files module
  • Never construct SQL from user input — SQLAlchemy handles parameterization

Named Constants

# WRONG
if status == "completed":
    ...

# RIGHT
JOB_STATUS_COMPLETED = "completed"
if status == JOB_STATUS_COMPLETED:
    ...
// WRONG
if (job.status === "completed") { ... }

// RIGHT
const JOB_STATUS_COMPLETED = "completed" as const;
if (job.status === JOB_STATUS_COMPLETED) { ... }