Thanks for your interest in contributing! This guide covers how to find work, how we triage it, and the conventions for adding database entities.
We keep a curated set of starter tasks so new contributors can land a first PR without wading through the whole backlog. Browse the live queries below:
- Good first issues — small, self-contained tasks suitable for a first contribution.
- Help wanted — tasks we'd like community help with, may need more context.
- Documentation — docs-only changes, a great low-risk starting point.
- Tests — test-only changes, also a good low-risk starting point.
If you're unsure where to start, pick a good first issue and comment on it to claim it. If a task turns out to be larger than expected, say so on the issue and we'll re-scope or re-label it.
We review the open backlog on a weekly cadence to keep the starter set healthy:
- Scan newly opened issues and label genuine starters with
good first issue. - Confirm existing
good first issuetasks are still accurate and unclaimed; remove the label if a task has grown in scope. - Keep the starter set at 10 or more open tasks so there is always something to pick up.
- Post a short weekly triage note summarizing what was added, re-labeled, or closed.
A task may be labeled good first issue only when it is:
- Docs-only (e.g.
documentation) or tests-only (e.g.tests), or an equally small, self-contained change. - Clearly scoped, with enough context in the issue body to complete it without deep codebase knowledge.
- Not on the money path and not otherwise hard or critical.
- Money-path issues — anything touching payments, billing, balances, payouts, or financial calculations.
- Hard, critical, or security-sensitive issues, or anything requiring broad architectural knowledge.
Mislabeling a hard issue as a starter wastes contributor time and dilutes the label. When in doubt, leave it unlabeled and ask in the issue.
All contributors are expected to follow our Code of Conduct.
When adding a new feature that requires a database table, follow this checklist to ensure your entity is properly registered:
-
Create the entity class in your module's
entities/directory (e.g.,src/mymodule/entities/my-entity.entity.ts)- Use
@Entity()decorator from TypeORM - Define all columns and relationships
- Use
-
Register in module's TypeOrmModule
- Add the entity to
TypeOrmModule.forFeature([MyEntity, ...])in your module's imports - This makes the entity available for dependency injection at runtime
- Add the entity to
-
Add to migration datasource (
backend/src/migration.datasource.ts)- Import your entity class
- Add it to the
entitiesarray in theDataSourceconfig - Why: Migrations run outside the NestJS DI container. The datasource must declare all entities so TypeORM CLI and migration runners can reference them. Without this, auto-migration generation and schema comparison may fail or produce incomplete migrations.
-
Create a migration if adding to existing tables
- If modifying an existing table:
npm run migration:generate -- src/mymodule/<timestamp>-DescribeChange - If creating a new table, you may rely on TypeORM's auto-generation or write SQL manually
- Ensure the migration is added to
migration.datasource.ts's migrations array
- If modifying an existing table:
-
Test
- Run
npm run migration:runlocally to verify the migration applies cleanly - Verify the table structure with
\d table_namein psql
- Run
// src/mymodule/entities/my-entity.entity.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity('my_entities')
export class MyEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
name: string;
}// src/mymodule/mymodule.module.ts
import { TypeOrmModule } from '@nestjs/typeorm';
import { MyEntity } from './entities/my-entity.entity';
@Module({
imports: [TypeOrmModule.forFeature([MyEntity])],
// ...
})
export class MyModule {}// backend/src/migration.datasource.ts
import { MyEntity } from './mymodule/entities/my-entity.entity';
export const migrationDataSource = new DataSource({
// ...
entities: [
// ... existing entities ...
MyEntity,
],
});Run the migration integration test to verify all registered entities' tables exist:
npm run test:migrationsThis test runs all migrations against a fresh Postgres instance and verifies that every expected table and column exists.