# Development guide

### Code Style

#### TypeScript
- Use TypeScript strict mode
- Define interfaces for all data structures
- Use type annotations for function parameters and returns

#### Angular
- Follow Angular style guide
- Use Angular CLI for scaffolding
- One component per file
- Use services for business logic

#### Naming Conventions
- Components: `PascalCase` (e.g., `WaybillListComponent`)
- Services: `PascalCase` with `Service` suffix (e.g., `WaybillService`)
- Modules: `PascalCase` with `Module` suffix (e.g., `WaybillModule`)
- Files: `kebab-case` (e.g., `waybill-list.component.ts`)

### Component Structure

```typescript
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-component-name',
  templateUrl: './component-name.component.html',
  styleUrls: ['./component-name.component.css']
})
export class ComponentNameComponent implements OnInit {
  constructor(private service: SomeService) { }

  ngOnInit(): void {
    // Initialization logic
  }
}
```

### Service Structure

```typescript
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class SomeService {
  constructor(private http: HttpClient) { }

  getData(): Observable<any> {
    const headers = new HttpHeaders({
      'Authorization': localStorage.getItem('jwt')!
    });
    return this.http.get<any>(API_URL, { headers });
  }
}
```

### Best Practices

#### 1. **Component Communication**
- Use `@Input()` for parent-to-child data flow
- Use `@Output()` with EventEmitter for child-to-parent events
- Use services for complex state management

#### 2. **Error Handling**
- Always handle Observable errors
- Provide user-friendly error messages
- Log errors for debugging

```typescript
this.service.getData().subscribe(
  data => this.data = data,
  error => {
    console.error('Error:', error);
    // Show error message to user
  }
);
```

#### 3. **Memory Management**
- Unsubscribe from Observables in `ngOnDestroy()`
- Use async pipe in templates when possible
- Avoid memory leaks

```typescript
private subscription: Subscription;

ngOnInit() {
  this.subscription = this.service.getData().subscribe(/*...*/);
}

ngOnDestroy() {
  this.subscription?.unsubscribe();
}
```

#### 4. **Performance**
- Use `trackBy` with `*ngFor` for large lists
- Implement `OnPush` change detection where appropriate
- Lazy load images and heavy components

#### 5. **Security**
- Never store sensitive data in localStorage (use httpOnly cookies)
- Sanitize user input
- Validate all data from API
- Use HTTPS in production

### Testing

#### Unit Tests
```bash
npm test
# Runs Karma test runner with Jasmine
```

#### E2E Tests
```bash
npm run e2e
# Runs Protractor for end-to-end tests
```

#### Writing Tests
```typescript
describe('ComponentName', () => {
  let component: ComponentName;
  let fixture: ComponentFixture<ComponentName>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ ComponentName ]
    }).compileComponents();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
```

### Linting

```bash
npm run lint
# Runs TSLint to check code quality
```

Fix linting issues automatically:
```bash
ng lint --fix
```

### Git Workflow

1. Create feature branch: `git checkout -b feature/feature-name`
2. Make changes and commit: `git commit -m "feat: description"`
3. Push to remote: `git push origin feature/feature-name`
4. Create pull request for review

**Commit Message Format:**
- `feat:` New feature
- `fix:` Bug fix
- `docs:` Documentation changes
- `style:` Code style changes
- `refactor:` Code refactoring
- `test:` Test additions/changes
- `chore:` Build/tooling changes