Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ files
coverage

settings.local.json
.codebuddy

# Environment variables
.env
Expand Down
105 changes: 2 additions & 103 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,109 +280,8 @@ The domain layer contains **only interfaces and pure business logic** with no ex
- `release.yml` - Builds and uploads assets on release, publishes to npm

### Adding New Features
1. Create Prisma schema changes in `src/core/infrastructure/db/schema.prisma`
2. Run `npm run migrate:dev` to create migration
3. Run `npm run generate` to update Prisma client
4. Add Repository in `src/core/domain/repositories/`:
```typescript
// Example: src/core/domain/repositories/FeatureRepository.ts
import { prisma } from '../../infrastructure/db/index.js';

const featureRepository = {
findAll: () => prisma.feature.findMany(),
findById: (id: number) => prisma.feature.findUnique({ where: { id } }),
create: (data) => prisma.feature.create({ data }),
update: (id, data) => prisma.feature.update({ where: { id }, data }),
remove: (id) => prisma.feature.delete({ where: { id } }),
};

export default featureRepository;
```
5. **Add tests for Repository** in `src/core/domain/repositories/__tests__/`:
```typescript
// Example: FeatureRepository.test.ts
import { describe, it, expect, beforeEach, vi } from 'vitest'
import { mockDeep, mockReset } from 'vitest-mock-extended'
import { PrismaClient } from '@prisma/client'
import featureRepository from '../FeatureRepository.js'

const prismaMock = mockDeep<PrismaClient>()
vi.mock('../../../infrastructure/db/index.js', () => ({ prisma: prismaMock }))

describe('featureRepository', () => {
beforeEach(() => { mockReset(prismaMock) })

it('should create feature', async () => {
prismaMock.feature.create.mockResolvedValue({ id: 1, name: 'test' })
const result = await featureRepository.create({ name: 'test' })
expect(result.id).toBe(1)
})
})
```
6. Add application services in `src/core/application/services/` if needed
7. **Add tests for services** in `src/core/application/services/__tests__/` if applicable
8. **Add IPC handler** in `src/main/ipc/handlers/feature.handler.ts`:
```typescript
import { ipcMain } from 'electron';
import featureRepository from '../../../core/domain/repositories/FeatureRepository.js';

export function registerFeatureHandlers() {
ipcMain.handle('feature:action', async (_, params) => {
try {
const result = await featureRepository.action(params);
return { success: true, data: result };
} catch (error: any) {
return { success: false, error: error.message };
}
});
console.log('[IPC] Feature handlers registered');
}
```
9. Register handler in `src/main/ipc/handlers/index.ts`
10. **Add tests for IPC handler** in `src/main/ipc/__tests__/handlers.test.ts`:
```typescript
it('should handle feature:action', async () => {
const mockData = { id: 1, name: 'test' }
vi.mocked(featureRepository.action).mockResolvedValue(mockData)

const result = await handlers.get('feature:action')!(null, params)

expect(result.success).toBe(true)
expect(result.data).toEqual(mockData)
})
```
11. **Add preload API** in `src/preload/index.ts`:
```typescript
feature: {
action: (params) => ipcRenderer.invoke('feature:action', params)
}
```
12. **Update TypeScript types** in `src/renderer/electron.d.ts`
13. Update React frontend components to use `window.api.feature.action()`
14. **Add component tests** in `src/renderer/components/__tests__/` (if new component):
```typescript
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import FeatureComponent from '../FeatureComponent'

describe('FeatureComponent', () => {
it('should render and interact', async () => {
window.api.feature.action = vi.fn().mockResolvedValue({ success: true })
render(<FeatureComponent />)
const button = screen.getByRole('button')
await userEvent.click(button)
expect(window.api.feature.action).toHaveBeenCalled()
})
})
```
15. **Add i18n translations** (if UI changes)
16. **Run tests** to ensure everything works:
```bash
npm run test:unit # Run unit tests
npm run test:renderer # Run component tests (if applicable)
npm run test:coverage # Check coverage
```
17. Run `npm run lint` and `npm run typecheck` and `npm run dev` to test

For detailed instructions on adding new features, including step-by-step development workflow, code examples, and testing guidelines, please refer to **[CONTRIBUTING.md](./CONTRIBUTING.md#adding-new-features)**.


### Electron Build Configuration
Expand Down
Loading
Loading