mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
- Rename logging-helper to logging for consistency - Remove git-commit-helper (superseded by /commit command) - Add git-workflow skill for Git Flow operations Co-Authored-By: Claude <noreply@anthropic.com>
588 lines
15 KiB
Markdown
588 lines
15 KiB
Markdown
# ISA-Frontend Architecture: Quick Reference Guide
|
|
|
|
## Project Overview at a Glance
|
|
|
|
| Aspect | Details |
|
|
|--------|---------|
|
|
| **Project Type** | Angular 20.3.6 Monorepo (Domain-Driven Design) |
|
|
| **Build Tool** | Nx 21.3.2 |
|
|
| **Total Libraries** | 63 (organized by domain + infrastructure) |
|
|
| **Main Application** | `isa-app` (only runnable app) |
|
|
| **Domains** | OMS, Remission, Checkout, Catalogue, Availability, CRM |
|
|
| **UI Components** | 17 specialized design system libraries |
|
|
| **Testing** | Jest (legacy) + Vitest (modern) - migration in progress |
|
|
| **State Management** | NgRx Signals with entity normalization |
|
|
| **API Clients** | 10 auto-generated from Swagger/OpenAPI specs |
|
|
| **Styling** | Tailwind CSS + 7 custom plugins |
|
|
| **Authentication** | OAuth2/OIDC via `angular-oauth2-oidc` |
|
|
| **Barcode Support** | Scandit Web Datacapture |
|
|
| **Analytics** | Matomo integration |
|
|
|
|
---
|
|
|
|
## Domain Summary
|
|
|
|
### 1. Order Management System (OMS) - 9 Libraries
|
|
**Focus:** Return workflows and receipt management
|
|
|
|
| Library | Purpose |
|
|
|---------|---------|
|
|
| `oms-data-access` | State + API integration |
|
|
| `oms-feature-return-search` | Receipt search interface |
|
|
| `oms-feature-return-details` | Item selection & configuration |
|
|
| `oms-feature-return-process` | Dynamic return questions |
|
|
| `oms-feature-return-summary` | Confirmation & printing |
|
|
| `oms-feature-return-review` | Completion review |
|
|
| `oms-shared-product-info` | Product display |
|
|
| `oms-shared-task-list` | Task management UI |
|
|
| `oms-utils-translation` | Receipt type labels |
|
|
|
|
**Key APIs:** oms-api, isa-api, print-api
|
|
|
|
---
|
|
|
|
### 2. Remission (Returns Management) - 8 Libraries
|
|
**Focus:** Warehouse return processing (mandatory + department)
|
|
|
|
| Library | Purpose |
|
|
|---------|---------|
|
|
| `remission-data-access` | State + API integration |
|
|
| `remission-feature-remission-list` | Main list view |
|
|
| `remission-feature-remission-return-receipt-list` | Receipt list |
|
|
| `remission-feature-remission-return-receipt-details` | Receipt details |
|
|
| `remission-shared-product` | Product components |
|
|
| `remission-shared-remission-start-dialog` | Start workflow |
|
|
| `remission-shared-return-receipt-actions` | Action buttons |
|
|
| `remission-shared-search-item-to-remit-dialog` | Item search |
|
|
|
|
**Key APIs:** Remission-specific via ISA backend
|
|
|
|
---
|
|
|
|
### 3. Checkout & Rewards - 6 Libraries
|
|
**Focus:** Shopping cart, orders, loyalty rewards
|
|
|
|
| Library | Purpose |
|
|
|---------|---------|
|
|
| `checkout-data-access` | Cart state + API |
|
|
| `checkout-feature-reward-catalog` | Reward browsing |
|
|
| `checkout-feature-reward-shopping-cart` | Cart with rewards |
|
|
| `checkout-feature-reward-order-confirmation` | Order confirmation |
|
|
| `checkout-shared-product-info` | Product display |
|
|
| `checkout-shared-reward-selection-dialog` | Reward selection |
|
|
|
|
**Key APIs:** checkout-api, crm-api (bonus cards)
|
|
|
|
---
|
|
|
|
### 4. Catalogue - 1 Library
|
|
**Focus:** Product search and discovery
|
|
|
|
| Library | Purpose |
|
|
|---------|---------|
|
|
| `catalogue-data-access` | Search + filtering |
|
|
|
|
**Key APIs:** cat-search-api, availability-api
|
|
|
|
---
|
|
|
|
### 5. Availability - 1 Library
|
|
**Focus:** Product stock checking
|
|
|
|
| Library | Purpose |
|
|
|---------|---------|
|
|
| `availability-data-access` | Stock queries |
|
|
|
|
**Key APIs:** availability-api
|
|
|
|
---
|
|
|
|
### 6. CRM - 1 Library
|
|
**Focus:** Customer data and bonus cards
|
|
|
|
| Library | Purpose |
|
|
|---------|---------|
|
|
| `crm-data-access` | Customer + bonus card state |
|
|
|
|
**Key APIs:** crm-api
|
|
|
|
---
|
|
|
|
## Architecture Layers
|
|
|
|
```
|
|
┌─────────────────────────────────┐
|
|
│ FEATURE LAYER (User-Facing) │
|
|
│ - Components with routes │
|
|
│ - User interactions │
|
|
│ - Navigation handlers │
|
|
└──────────────┬──────────────────┘
|
|
│ imports
|
|
┌──────────────▼──────────────────┐
|
|
│ SHARED LAYER (Reusable) │
|
|
│ - UI components (17 libs) │
|
|
│ - Shared components (7 libs) │
|
|
│ - Domain shared │
|
|
└──────────────┬──────────────────┘
|
|
│ imports
|
|
┌──────────────▼──────────────────┐
|
|
│ DATA ACCESS LAYER (State) │
|
|
│ - NgRx Signal Stores │
|
|
│ - API Services │
|
|
│ - Entity management │
|
|
└──────────────┬──────────────────┘
|
|
│ imports
|
|
┌──────────────▼──────────────────┐
|
|
│ INFRASTRUCTURE (Foundation) │
|
|
│ - Core libraries (5) │
|
|
│ - Common utilities (3) │
|
|
│ - Generated APIs (10) │
|
|
│ - Utilities (3) │
|
|
└─────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## State Management Pattern
|
|
|
|
### NgRx Signals Store Structure
|
|
|
|
```typescript
|
|
export const orderStore = signalStore(
|
|
// 1. State definition
|
|
withState({
|
|
orders: [] as Order[],
|
|
selected: null as Order | null,
|
|
loading: false,
|
|
error: null as Error | null,
|
|
}),
|
|
|
|
// 2. Entity management (auto-normalization)
|
|
withEntities({ entity: type<Order>() }),
|
|
|
|
// 3. Computed values
|
|
withComputed((store) => ({
|
|
orderCount: computed(() => store.orders().length),
|
|
hasSelected: computed(() => store.selected() !== null),
|
|
})),
|
|
|
|
// 4. Methods for state mutations
|
|
withMethods((store, api = inject(OmsApiService)) => ({
|
|
load: rxMethod<void>(
|
|
pipe(
|
|
tapResponse(
|
|
(orders) => patchState(store, setAllEntities(orders)),
|
|
(error) => handleError(error)
|
|
)
|
|
)
|
|
),
|
|
select: (order: Order) => {
|
|
patchState(store, { selected: order });
|
|
},
|
|
})),
|
|
|
|
// 5. Auto persistence
|
|
withStorage({ key: 'orders' }),
|
|
|
|
// 6. Cleanup hooks
|
|
withHooks({
|
|
onInit: ({ load }) => load(),
|
|
onDestroy: () => console.log('Store destroyed'),
|
|
})
|
|
);
|
|
```
|
|
|
|
**Key Features:**
|
|
- Signals: Reactive properties
|
|
- Entity management: Auto-normalized state
|
|
- Methods: Encapsulated mutations
|
|
- Storage: Automatic persistence
|
|
- Hooks: Lifecycle management
|
|
|
|
---
|
|
|
|
## Component Structure
|
|
|
|
### Standalone Component Example
|
|
|
|
```typescript
|
|
@Component({
|
|
selector: 'oms-return-search',
|
|
standalone: true,
|
|
imports: [
|
|
CommonModule,
|
|
ReactiveFormsModule,
|
|
// Shared components
|
|
UiSearchBar,
|
|
UiButton,
|
|
OmsProductInfo,
|
|
UiEmptyState,
|
|
],
|
|
template: `
|
|
<div class="container">
|
|
<ui-search-bar (search)="onSearch($event)" />
|
|
|
|
@if (store.receipts(); as receipts) {
|
|
@if (receipts.length > 0) {
|
|
<oms-product-info
|
|
*ngFor="let receipt of receipts"
|
|
[receipt]="receipt"
|
|
/>
|
|
} @else {
|
|
<ui-empty-state title="Keine Belege" />
|
|
}
|
|
} @loading {
|
|
<ui-skeleton-loader />
|
|
}
|
|
</div>
|
|
`,
|
|
styles: [`...`],
|
|
})
|
|
export class OmsReturnSearchComponent {
|
|
protected store = inject(omsStore);
|
|
private api = inject(OmsApiService);
|
|
|
|
onSearch(term: string) {
|
|
this.store.searchReceipts(term);
|
|
}
|
|
}
|
|
```
|
|
|
|
**Best Practices:**
|
|
- ✅ Standalone components only
|
|
- ✅ Explicit imports
|
|
- ✅ Inject store, not services
|
|
- ✅ Use store methods directly
|
|
- ✅ Let control flow (@if, @for)
|
|
|
|
---
|
|
|
|
## Common Patterns
|
|
|
|
### 1. Search with Debouncing
|
|
|
|
```typescript
|
|
export class SearchComponent {
|
|
private searchTerm$ = new Subject<string>();
|
|
|
|
results$ = this.searchTerm$.pipe(
|
|
debounceTime(300),
|
|
distinctUntilChanged(),
|
|
switchMap((term) => this.api.search(term)),
|
|
takeUntilKeydown('Escape')
|
|
);
|
|
|
|
onSearch(term: string) {
|
|
this.searchTerm$.next(term);
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2. Modal/Dialog Handling
|
|
|
|
```typescript
|
|
export class DialogComponent {
|
|
private dialog = inject(DialogService);
|
|
|
|
openRewardSelection() {
|
|
this.dialog.open(RewardSelectionDialog, {
|
|
data: { cart: this.cart },
|
|
}).afterClosed$.subscribe((reward) => {
|
|
if (reward) {
|
|
this.store.selectReward(reward);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Form Validation
|
|
|
|
```typescript
|
|
export class ReturnProcessComponent {
|
|
form = new FormGroup({
|
|
reason: new FormControl('', [Validators.required]),
|
|
quantity: new FormControl(1, [Validators.min(1)]),
|
|
comments: new FormControl(''),
|
|
});
|
|
|
|
submit() {
|
|
if (this.form.valid) {
|
|
this.store.submitReturn(this.form.value);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 4. Responsive Design
|
|
|
|
```typescript
|
|
export class ResponsiveComponent {
|
|
// Use breakpoint service instead of CSS-only
|
|
isDesktop = breakpoint([
|
|
Breakpoint.Desktop,
|
|
Breakpoint.DesktopL,
|
|
Breakpoint.DesktopXL,
|
|
]);
|
|
|
|
template = `
|
|
@if (isDesktop()) {
|
|
<desktop-layout />
|
|
} @else {
|
|
<mobile-layout />
|
|
}
|
|
`;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Common Commands
|
|
|
|
### Development
|
|
```bash
|
|
npm start # Start with SSL
|
|
npm test # Test all libraries
|
|
npm run build # Dev build
|
|
npm run build-prod # Production build
|
|
```
|
|
|
|
### Testing
|
|
```bash
|
|
npx nx test oms-data-access --skip-nx-cache
|
|
npx nx affected:test --skip-nx-cache
|
|
npm run ci # CI with coverage
|
|
```
|
|
|
|
### Code Quality
|
|
```bash
|
|
npm run lint # ESLint
|
|
npm run prettier # Format code
|
|
npm run docs:generate # Update library ref
|
|
```
|
|
|
|
### API & Swagger
|
|
```bash
|
|
npm run generate:swagger # Regenerate all APIs
|
|
npm run fix:files:swagger # Unicode cleanup
|
|
```
|
|
|
|
### Dependency Analysis
|
|
```bash
|
|
npx nx graph # Visual dependency graph
|
|
npx nx show project oms-data-access --web false
|
|
npx nx affected:lint --skip-nx-cache
|
|
```
|
|
|
|
---
|
|
|
|
## File Organization by Domain
|
|
|
|
### OMS Domain Structure
|
|
```
|
|
libs/oms/
|
|
├── data-access/
|
|
│ └── src/
|
|
│ ├── index.ts
|
|
│ ├── stores/
|
|
│ │ ├── receipt.store.ts
|
|
│ │ └── return.store.ts
|
|
│ └── services/
|
|
│ ├── oms-api.service.ts
|
|
│ └── print.service.ts
|
|
├── feature/
|
|
│ ├── return-search/
|
|
│ ├── return-details/
|
|
│ ├── return-process/
|
|
│ ├── return-summary/
|
|
│ └── return-review/
|
|
├── shared/
|
|
│ ├── product-info/
|
|
│ └── task-list/
|
|
└── utils/
|
|
└── translation/
|
|
```
|
|
|
|
### UI Component Structure
|
|
```
|
|
libs/ui/buttons/
|
|
├── src/
|
|
│ ├── index.ts
|
|
│ ├── primary-button.component.ts
|
|
│ ├── secondary-button.component.ts
|
|
│ ├── ...
|
|
│ └── buttons.module.ts
|
|
├── README.md
|
|
├── project.json
|
|
└── ...
|
|
```
|
|
|
|
---
|
|
|
|
## TypeScript Path Aliases
|
|
|
|
```json
|
|
{
|
|
"paths": {
|
|
// Domain data-access
|
|
"@isa/oms/data-access": ["libs/oms/data-access/src/index.ts"],
|
|
"@isa/remission/data-access": ["libs/remission/data-access/src/index.ts"],
|
|
|
|
// UI components
|
|
"@isa/ui/buttons": ["libs/ui/buttons/src/index.ts"],
|
|
"@isa/ui/dialog": ["libs/ui/dialog/src/index.ts"],
|
|
|
|
// Core infrastructure
|
|
"@isa/core/logging": ["libs/core/logging/src/index.ts"],
|
|
"@isa/core/storage": ["libs/core/storage/src/index.ts"],
|
|
|
|
// Generated APIs
|
|
"@generated/swagger/oms-api": ["generated/swagger/oms-api/src/index.ts"]
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Styling & Design System
|
|
|
|
### Tailwind Utilities (ISA-Specific)
|
|
|
|
```html
|
|
<!-- Brand Colors -->
|
|
<div class="text-isa-accent-primary">Primary text</div>
|
|
<button class="bg-isa-accent-primary">Primary button</button>
|
|
|
|
<!-- Typography -->
|
|
<h1 class="isa-text-heading-1-bold">Large heading</h1>
|
|
<p class="isa-text-body-2-regular">Body text</p>
|
|
|
|
<!-- Custom Breakpoints -->
|
|
<div class="hidden isa-desktop:block">Desktop only</div>
|
|
<div class="block isa-desktop:hidden">Mobile only</div>
|
|
|
|
<!-- Custom Plugins -->
|
|
<button class="isa-button-primary">ISA Button</button>
|
|
<div class="isa-input-group">...</div>
|
|
```
|
|
|
|
### Custom Tailwind Plugins
|
|
1. button - Button styling
|
|
2. typography - Text utilities
|
|
3. menu - Menu styling
|
|
4. label - Label & tag styling
|
|
5. input - Input styling
|
|
6. section - Section containers
|
|
7. select-bullet - Select styling
|
|
|
|
---
|
|
|
|
## Testing Approach
|
|
|
|
### New Libraries (Vitest + Angular Testing Utils)
|
|
```typescript
|
|
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
|
import { OmsReturnSearchComponent } from './oms-return-search.component';
|
|
|
|
describe('OmsReturnSearchComponent', () => {
|
|
let component: OmsReturnSearchComponent;
|
|
let fixture: ComponentFixture<OmsReturnSearchComponent>;
|
|
|
|
beforeEach(async () => {
|
|
await TestBed.configureTestingModule({
|
|
imports: [OmsReturnSearchComponent],
|
|
}).compileComponents();
|
|
|
|
fixture = TestBed.createComponent(OmsReturnSearchComponent);
|
|
component = fixture.componentInstance;
|
|
fixture.detectChanges();
|
|
});
|
|
|
|
it('should create', () => {
|
|
expect(component).toBeTruthy();
|
|
});
|
|
});
|
|
```
|
|
|
|
### E2E Attributes
|
|
All templates must include data attributes:
|
|
```html
|
|
<button
|
|
data-what="submit-return"
|
|
data-which="primary-action"
|
|
[attr.data-order-id]="orderId"
|
|
>
|
|
Submit Return
|
|
</button>
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
| Issue | Solution |
|
|
|-------|----------|
|
|
| **Build cache stale** | `npx nx reset` or `--skip-nx-cache` |
|
|
| **Test failures** | Always use `--skip-nx-cache` |
|
|
| **Import not found** | Check `tsconfig.base.json` path alias |
|
|
| **Circular dependency** | Run `npx nx lint` to identify |
|
|
| **SSL certificate error** | Accept localhost certificate in browser |
|
|
| **State not persisting** | Check `withStorage()` in store |
|
|
| **API 401 Unauthorized** | Verify OAuth2 token in auth service |
|
|
|
|
---
|
|
|
|
## Quick Links
|
|
|
|
- **Library Reference:** `/docs/library-reference.md`
|
|
- **Architecture Analysis:** `/docs/architecture-analysis.md`
|
|
- **Dependency Hierarchy:** `/docs/dependency-hierarchy.md`
|
|
- **Testing Guidelines:** `/docs/guidelines/testing.md`
|
|
- **Nx Documentation:** https://nx.dev/
|
|
- **Angular Documentation:** https://angular.io/
|
|
- **NgRx Signals:** https://ngrx.io/guide/signals
|
|
|
|
---
|
|
|
|
## Getting Help
|
|
|
|
1. Check library README: `libs/[domain]/[layer]/[feature]/README.md`
|
|
2. Review existing examples in similar domains
|
|
3. Check `npx nx show project [project-name]`
|
|
4. Read CLAUDE.md for project-specific conventions
|
|
5. Review git history: `git log --oneline libs/[domain]`
|
|
|
|
---
|
|
|
|
## Performance Budgets
|
|
|
|
- **Main bundle:** 2MB warning, 5MB error (gzipped)
|
|
- **Initial load:** < 2s on 4G
|
|
- **Core (after auth):** < 5s
|
|
|
|
**Bundle Analysis:**
|
|
```bash
|
|
npx nx build isa-app --configuration=production --stats-json
|
|
webpack-bundle-analyzer dist/isa-app/browser/stats.json
|
|
```
|
|
|
|
---
|
|
|
|
## Monorepo Statistics
|
|
|
|
| Metric | Count |
|
|
|--------|-------|
|
|
| Total Libraries | 63 |
|
|
| Feature Components | 20 |
|
|
| UI Components | 17 |
|
|
| Data Access | 6 |
|
|
| Core Infrastructure | 5 |
|
|
| Shared Components | 7 |
|
|
| Utilities | 3 |
|
|
| Generated APIs | 10 |
|
|
| Lines of Code | ~500K+ |
|
|
| TypeScript Files | ~1,500 |
|
|
| Test Files | ~400 |
|
|
| Generated Test Coverage | Vitest: 34%, Jest: 65% |
|
|
|