221 lines
6.2 KiB
Markdown
221 lines
6.2 KiB
Markdown
# Phase 4: Service Layer Refactor - Checklist
|
|
|
|
## ✅ Completed Tasks
|
|
|
|
### Customer Service Refactor
|
|
|
|
- [x] Analyze existing customer service structure
|
|
- [x] Update customer service with branch context integration
|
|
- [x] Implement contact visibility logic (private-by-default)
|
|
- [x] Add `BranchContext` parameter to all customer operations
|
|
- [x] Implement contact sharing/unsharing functionality
|
|
- [x] Add business rule validation for quotation creation
|
|
- [x] Create `generateCrmCustomerCode` utility function
|
|
- [x] Add soft delete support for customers
|
|
- [x] Implement CRUD operations with branch scoping
|
|
|
|
### Quotation Service Refactor
|
|
|
|
- [x] Analyze existing quotation service structure
|
|
- [x] Add multi-currency support (THB, USD, EUR, JPY, CNY)
|
|
- [x] Implement exchange rate capture at quotation creation
|
|
- [x] Add base currency amount calculation
|
|
- [x] Implement quotation revision system
|
|
- [x] Add `parentQuotationId` and `revisionNo` tracking
|
|
- [x] Create `createQuotationRevision` function with cloning logic
|
|
- [x] Implement quotation item management
|
|
- [x] Add quotation customer relationship management
|
|
- [x] Create multi-currency calculation utilities
|
|
- [x] Add quotation validation rules (editable, sendable status checks)
|
|
- [x] Implement `generateQuotationCode` utility function
|
|
|
|
## 📁 Created Files
|
|
|
|
1. **`src/modules/customers/service.refactored.ts`**
|
|
- Customer operations with branch scoping
|
|
- Contact visibility enforcement
|
|
- Contact sharing functionality
|
|
- Business rule validations
|
|
|
|
2. **`src/modules/quotations/service.refactored.ts`**
|
|
- Quotation CRUD with branch context
|
|
- Multi-currency support
|
|
- Revision system implementation
|
|
- Currency conversion utilities
|
|
- Validation helpers
|
|
|
|
## 🔑 Key Features Implemented
|
|
|
|
### Branch Scoping
|
|
|
|
- All operations automatically scoped by `currentBranchId`
|
|
- Cross-branch access prevented at service layer
|
|
- Automatic branch ID injection on create/update operations
|
|
|
|
### Contact Visibility Logic
|
|
|
|
```
|
|
Visibility Rule: User can see contact IF:
|
|
- createdBy == currentUser
|
|
OR
|
|
- isPublic == true
|
|
```
|
|
|
|
### Multi-Currency Support
|
|
|
|
- Currency code stored with each quotation
|
|
- Exchange rate captured at creation time (immutable)
|
|
- Base currency (THB) amount calculated and stored
|
|
- Same quotation code can have multiple currency versions
|
|
|
|
### Revision System
|
|
|
|
```
|
|
Quotation Status Flow:
|
|
DRAFT → SENT (locked)
|
|
SENT → Create REVISION (new draft)
|
|
REVISION → SENT (locked)
|
|
SENT → ACCEPTED | REJECTED
|
|
```
|
|
|
|
### Business Rules
|
|
|
|
- ✅ User must have visible contacts to create quotation
|
|
- ✅ Only creator can update/delete their contacts
|
|
- ✅ Sent quotations cannot be edited directly (must create revision)
|
|
- ✅ Draft quotations are editable
|
|
|
|
## 📊 Database Integration
|
|
|
|
### Customer Service
|
|
|
|
- Uses Drizzle ORM with PostgreSQL
|
|
- Implements proper foreign key relationships
|
|
- Supports soft deletes with `deletedAt` timestamp
|
|
- Indexes: branchId, customerStatus, crmCustomerCode, erpCustomerCode
|
|
|
|
### Quotation Service
|
|
|
|
- Full Drizzle ORM integration
|
|
- Multi-table transactions (quotations, items, customers)
|
|
- Proper cascade deletes
|
|
- Indexes: branchId, code, status, quotationDate, parentQuotationId
|
|
|
|
## 🔄 Migration Notes
|
|
|
|
### From Old Service to New Service
|
|
|
|
**Old Pattern:**
|
|
|
|
```typescript
|
|
export function getAllCustomers(branch: string): Customer[] {
|
|
return getCustomersByBranch(branch);
|
|
}
|
|
```
|
|
|
|
**New Pattern:**
|
|
|
|
```typescript
|
|
export async function getCustomersByBranch(
|
|
context: BranchContext,
|
|
status?: string,
|
|
): Promise<Customer[]> {
|
|
const { currentBranchId } = context;
|
|
return await db
|
|
.select()
|
|
.from(customers)
|
|
.where(eq(customers.branchId, currentBranchId));
|
|
}
|
|
```
|
|
|
|
### Breaking Changes
|
|
|
|
1. All functions now require `BranchContext` parameter
|
|
2. Functions are now async (return Promises)
|
|
3. Contact visibility is enforced by default
|
|
4. Multi-currency fields are required for quotations
|
|
|
|
## 🧪 Testing Recommendations
|
|
|
|
### Unit Tests Needed
|
|
|
|
- [ ] Test branch scoping enforcement
|
|
- [ ] Test contact visibility rules
|
|
- [ ] Test contact sharing/unsharing
|
|
- [ ] Test multi-currency calculations
|
|
- [ ] Test revision creation logic
|
|
- [ ] Test quotation validation rules
|
|
- [ ] Test soft delete functionality
|
|
|
|
### Integration Tests Needed
|
|
|
|
- [ ] Test full quotation creation flow
|
|
- [ ] Test quotation revision flow
|
|
- [ ] Test customer + contact creation flow
|
|
- [ ] Test cross-branch access prevention
|
|
- [ ] Test currency conversion accuracy
|
|
|
|
## 📋 Next Steps
|
|
|
|
### Phase 5: Controllers Update
|
|
|
|
- [ ] Update customer controllers to use refactored service
|
|
- [ ] Update quotation controllers to use refactored service
|
|
- [ ] Add BranchContext injection from middleware
|
|
- [ ] Update API request/response types
|
|
- [ ] Add error handling for validation failures
|
|
|
|
### Phase 6: Models (TypeScript)
|
|
|
|
- [ ] Update customer model types for new fields
|
|
- [ ] Add quotation model types with multi-currency
|
|
- [ ] Create contact model types
|
|
- [ ] Add revision-related types
|
|
- [ ] Update ElysiaJS validation schemas
|
|
|
|
### Phase 7: Testing
|
|
|
|
- [ ] Write unit tests for customer service
|
|
- [ ] Write unit tests for quotation service
|
|
- [ ] Write integration tests for API endpoints
|
|
- [ ] Test multi-tenant scenarios
|
|
- [ ] Test multi-currency scenarios
|
|
|
|
## 🎯 Success Criteria
|
|
|
|
Phase 4 is complete when:
|
|
|
|
- [x] All service functions use BranchContext
|
|
- [x] Contact visibility is enforced
|
|
- [x] Multi-currency is fully supported
|
|
- [x] Revision system works correctly
|
|
- [ ] Controllers are updated (Phase 5)
|
|
- [ ] Models are updated (Phase 6)
|
|
- [ ] Tests pass (Phase 7)
|
|
|
|
## 📝 Notes
|
|
|
|
### Contact Visibility Implementation
|
|
|
|
- The contact visibility is implemented at the service layer using `isPublic` flag
|
|
- Future enhancement: Add `contact_shares` table for more granular sharing (specific users)
|
|
- Current implementation: Public/Private binary flag
|
|
|
|
### Multi-Currency Implementation
|
|
|
|
- Exchange rates are captured at quotation creation time
|
|
- Historical rates are preserved (no dynamic recalculation)
|
|
- Base currency (THB) is used for reporting and comparisons
|
|
|
|
### Revision System
|
|
|
|
- Each revision creates a new quotation record
|
|
- Parent relationship tracked via `parentQuotationId`
|
|
- Same quotation code shared across revisions
|
|
- Status resets to "draft" for new revisions
|
|
|
|
---
|
|
|
|
**Phase 4 Status**: ✅ **CORE IMPLEMENTATION COMPLETE**
|
|
**Next Phase**: Phase 5 - Controllers Update
|