docs/principles.md

Engineering principles

First principles for studyflash engineering. Apply across every app, package, and service.

publishedrajivprinciplesconventions

Three rules that apply everywhere. When a decision is hard, default to these.

1. No typecasting

Typecasting is a code smell. If you need to cast, the types are wrong — fix the types, don't paper over them. as any and unsafe assertions hide bugs at the boundary where you most need clarity.

Exceptions are rare and should be named: e.g. interop with an untyped third-party API at the entry point, with the cast immediately wrapped in a validated boundary.

2. Don't repeat yourself

Duplication is a code smell. Extract shared logic into packages/* or local utilities. Three similar lines is fine; the same five-line block in three apps means a missing package.

Caveat: don't pre-abstract. Wait until the third occurrence before extracting. Premature abstraction is worse than honest duplication.

3. Everything declarative

Infrastructure as code (Pulumi), CI/CD as config, environment as definition. No manual production steps. If you patched something via the dashboard / CLI / kubectl, you owe a follow-up PR that makes it declarative.

This applies to:

  • Infra changes → Pulumi, never direct API/CLI patches
  • CI workflows → committed YAML, never editing in GitHub UI
  • Feature gates / rollouts → flag config in code, not toggled by-hand
  • Database schema → migrations, not ad-hoc SQL