Files
QuantEngineByItz/oms-wms-erp/PHASE2-ROADMAP.md
T
kjh2064 b34b0dd7d6
Validators (Pushes and Pull Requests) / UI & Storage Validation (pull_request) Failing after 12s
Validators (Pushes and Pull Requests) / Database & Schema Validation (pull_request) Successful in 13s
Validators (Pushes and Pull Requests) / Core Validators & Database Setup (pull_request) Failing after 28s
Validators (Pushes and Pull Requests) / WBS & Audit Validations (pull_request) Has been skipped
Validators (Pushes and Pull Requests) / .NET Contracts (pull_request) Has been skipped
Validators (Pushes and Pull Requests) / Calibration & Performance (pull_request) Has been skipped
Validators (Pushes and Pull Requests) / Operational Report & Decision Packet (pull_request) Has been skipped
Validators (Pushes and Pull Requests) / CI Workflow Lint (pull_request) Failing after 10s
Validators (Pushes and Pull Requests) / Security & Secrets (pull_request) Successful in 12s
Validators (Pushes and Pull Requests) / Notify PR Results (pull_request) Successful in 2s
Frontend CI Pipeline / ci-frontend-8-steps (pull_request) Failing after 2m50s
Add OMS WMS ERP platform
2026-07-27 00:45:39 +09:00

444 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 2 Roadmap: Typed Fields & Pinia Stores
**Duration**: Week 3-4 (2026-08-12 → 2026-08-26)
**Goal**: Build Layer 2 (Typed Fields) + State Management (Pinia)
---
## Phase 2 Structure
### Step 1: Typed Fields (Layer 2) — Week 3
- 12 Typed Field components
- Validation & Formatting utilities
- 100+ Storybook stories
- 70+ integration tests
### Step 2: Pinia Stores — Week 4
- 10 store modules (orders, inventory, products, etc.)
- API client setup
- Mock Service Worker (MSW)
- State management patterns
### Step 3: API Integration — Week 4
- OpenAPI SDK auto-generation
- API client wrapper
- Error handling middleware
- Request/response interceptors
### Step 4: Integration Testing — Week 4
- Form validation chains
- API mock testing (MSW)
- State mutation testing
- E2E test scenarios (50+)
---
## Phase 2 Step 1: Typed Fields (Week 3)
### Completed (5/12) ✅
1. **TextField** — Text inputs with validation
- Types: text, email, password, url, tel
- File: src/components/fields/typed/TextField/
- Stories: 8+
- Tests: 5+
2. **DateField** — Date picker
- Format: YYYY-MM-DD (ISO)
- Min/Max validation
- File: src/components/fields/typed/DateField/
- Stories: 8+
- Tests: 5+
3. **CurrencyField** — Amount input with formatting
- Locale: Korean (₩)
- Decimals: configurable
- File: src/components/fields/typed/CurrencyField/
- Stories: 10+
- Tests: 5+
4. **SelectField** — Dropdown with validation
- Options: typed array
- Searchable: ready
- File: src/components/fields/typed/SelectField/
- Stories: 8+
- Tests: 5+
5. **StatusField** — Predefined status selector
- Statuses: DRAFT, PENDING, APPROVED, ACTIVE, COMPLETED, CANCELLED, FAILED
- Colors: status-based badges
- File: src/components/fields/typed/StatusField/
- Stories: 8+
- Tests: 5+
### Templates (7/12) — Ready to Implement
6. TimeField (time picker, HH:mm)
7. PercentageField (0-100%, formatted)
8. QuantityField (positive integers)
9. MultiSelectField (array of values)
10. CheckboxField (boolean)
11. SearchField (autocomplete with API)
12. PhoneField (formatted phone)
### Shared Utilities ✅
**useValidation.ts** — Validation composable
```typescript
- required, email, minLength, maxLength
- min, max, pattern, numeric
- positiveInteger, percentage, url
- Chainable: validator.validate(value, [rule1, rule2])
```
**useFormatting.ts** — Formatting composable
```typescript
- formatCurrency, parseCurrency
- formatDate, parseDate, formatTime, parseTime
- formatPhone, parsePhone
- formatNumber, truncate, capitalize
```
### Testing (Phase 2 Step 1)
**Unit Tests**: 5-8 per field × 12 = 60-96 tests
- Props validation
- Event emissions
- Error handling
- Formatting/parsing
**Storybook**: 8-12 stories per field × 12 = 96-144 stories
- Default state
- Disabled state
- With error
- With help text
- With validation
- Edge cases
**Target**: All stories render, all tests PASS by 2026-08-19
---
## Phase 2 Step 2: Pinia Stores (Week 4)
### 10 Store Modules
```
src/stores/modules/
├── orders.ts (OMS: Order management)
├── inventory.ts (WMS: Stock levels)
├── products.ts (ERP: Product master)
├── customers.ts (OMS: Customer master)
├── suppliers.ts (ERP: Supplier master)
├── stockTransfers.ts (WMS: Stock movements)
├── glAccounts.ts (ERP: GL accounting)
├── vouchers.ts (ERP: Journal entries)
├── users.ts (Admin: User management)
└── warehouses.ts (WMS: Warehouse master)
```
### Store Structure (Composition API)
```typescript
// Each store follows this pattern:
export const useOrderStore = defineStore('orders', () => {
// State
const orders = ref<Order[]>([])
const selectedOrder = ref<Order | null>(null)
const loading = ref(false)
const error = ref<string | null>(null)
const filters = ref({...})
// Computed
const orderCount = computed(() => orders.value.length)
const filteredOrders = computed(() => {...})
const totalAmount = computed(() => {...})
// Actions (async)
const fetchOrders = async () => {...}
const createOrder = async (payload) => {...}
const updateOrder = async (id, payload) => {...}
const deleteOrder = async (id) => {...}
// Mutations
const setFilter = (key, value) => {...}
const clearFilters = () => {...}
return {
// State
orders, selectedOrder, loading, error, filters,
// Computed
orderCount, filteredOrders, totalAmount,
// Actions
fetchOrders, createOrder, updateOrder, deleteOrder,
// Mutations
setFilter, clearFilters
}
})
```
### Example: Orders Store
```typescript
// State
- orders: Order[]
- selectedOrder: Order | null
- loading: boolean
- error: string | null
- filters: {status, dateRange, customerId}
// Computed
- orderCount: number
- filteredOrders: Order[]
- totalAmount: number
// Actions
- fetchOrders(limit, offset)
- fetchOrderById(orderId)
- createOrder(payload)
- updateOrder(orderId, payload)
- deleteOrder(orderId)
// Mutations
- setFilter(key, value)
- clearFilters()
```
### Store Setup (src/stores/index.ts)
```typescript
export { useOrderStore } from './modules/orders'
export { useInventoryStore } from './modules/inventory'
export { useProductStore } from './modules/products'
export { useCustomerStore } from './modules/customers'
// ... etc
```
### Usage in Components
```vue
<script setup lang="ts">
import { useOrderStore } from '@/stores'
const orderStore = useOrderStore()
// Access state
const orders = orderStore.orders
const loading = orderStore.loading
// Access computed
const filteredOrders = orderStore.filteredOrders
// Call actions
await orderStore.fetchOrders(100, 0)
await orderStore.createOrder({...})
</script>
```
---
## Phase 2 Step 3: API Client Integration
### OpenAPI SDK Generation
```bash
# From spec/63_oms_wms_erp_api_openapi.yaml
npx @openapi-generator/cli generate \
-i ../../spec/63_oms_wms_erp_api_openapi.yaml \
-g typescript-axios \
-o src/services/api/generated
```
### Generated Files
```
src/services/api/generated/
├── models/
│ ├── Order.ts
│ ├── OrderLine.ts
│ ├── Inventory.ts
│ └── ... (all 15 models)
├── apis/
│ ├── OrdersApi.ts
│ ├── InventoryApi.ts
│ ├── ProductsApi.ts
│ └── ... (all 11 resources)
└── index.ts
```
### API Client Wrapper (src/services/api/client.ts)
```typescript
import axios from 'axios'
import { Configuration, OrdersApi, InventoryApi, ... } from './generated'
const apiConfig = new Configuration({
basePath: process.env.VITE_API_BASE_URL || 'http://localhost:3000/api'
})
export const ordersApi = new OrdersApi(apiConfig)
export const inventoryApi = new InventoryApi(apiConfig)
export const productsApi = new ProductsApi(apiConfig)
// ... etc
```
### Pinia Integration
```typescript
// In store: const response = await ordersApi.listOrders({ limit, offset })
export const useOrderStore = defineStore('orders', () => {
const fetchOrders = async () => {
try {
const response = await ordersApi.listOrders({ limit: 100, offset: 0 })
orders.value = response.data
} catch (err) {
error.value = (err as Error).message
}
}
// ...
})
```
---
## Phase 2 Step 4: Integration Testing
### Mock Service Worker (MSW) Setup
```typescript
// tests/mocks/handlers.ts
import { http, HttpResponse } from 'msw'
export const handlers = [
http.get('/api/orders', () => {
return HttpResponse.json([
{ orderId: '1', orderNo: 'ORD-001', status: 'DRAFT', ... }
])
}),
http.post('/api/orders', ({ request }) => {
return HttpResponse.json(
{ orderId: '2', orderNo: 'ORD-002', ... },
{ status: 201 }
)
}),
// ... more handlers
]
```
### Integration Test Example
```typescript
// tests/integration/orders.spec.ts
describe('Orders Store with API', () => {
beforeEach(() => {
server.listen()
})
afterEach(() => {
server.close()
})
it('fetches orders from API', async () => {
const store = useOrderStore()
await store.fetchOrders()
expect(store.orders).toHaveLength(1)
expect(store.orders[0].orderNo).toBe('ORD-001')
})
it('creates new order', async () => {
const store = useOrderStore()
const newOrder = await store.createOrder({ customerId: 'CUST-001' })
expect(newOrder.orderId).toBe('2')
})
})
```
### E2E Test Scenarios (50+)
```typescript
// tests/e2e/order-workflow.spec.ts
test('Complete order workflow', async ({ page }) => {
// 1. Navigate to orders
await page.goto('/admin/orders')
// 2. Create order
await page.click('button:text("Create")')
await page.fill('[name="customerId"]', 'CUST-001')
await page.fill('[name="quantity"]', '100')
await page.click('button:text("Submit")')
// 3. Verify order created
await expect(page).toContainText('Order created')
// 4. Edit order
await page.click('button:text("Edit")')
await page.fill('[name="quantity"]', '150')
await page.click('button:text("Save")')
// 5. Verify audit trail
await page.goto('/admin/audit-logs')
await expect(page).toContainText('Order updated')
})
```
---
## Phase 2 Completion Criteria
### By End of Week 3 (2026-08-19)
- ✅ All 12 Typed Fields implemented
- ✅ All Storybook stories rendering (100+ stories)
- ✅ All unit tests passing (70+ tests)
- ✅ Validation composable complete
- ✅ Formatting composable complete
### By End of Week 4 (2026-08-26)
- ✅ All 10 Pinia stores implemented
- ✅ OpenAPI SDK generated
- ✅ API client wrapper complete
- ✅ MSW setup for testing
- ✅ 50+ integration tests passing
- ✅ 50+ E2E test scenarios passing
---
## Success Metrics
| Metric | Target | Status |
|--------|--------|--------|
| Typed Fields | 12/12 | 5/12 ✅ |
| Storybook Stories | 100+ | Planned |
| Unit Tests | 70+ | Planned |
| Integration Tests | 50+ | Planned |
| E2E Tests | 50+ | Planned |
| Code Coverage | 70%+ | Target |
| Lighthouse Score | 90+ | Target |
| Bundle Size | <500MB | Target |
---
## Timeline
```
Week 3 (2026-08-12 → 2026-08-19)
├─ Step 1.1: Generate 7 remaining Typed Fields (Mon-Tue)
├─ Step 1.2: Add Storybook stories for all 12 (Wed-Thu)
├─ Step 1.3: Add unit tests for all 12 (Fri)
└─ Deliverable: 12 Typed Fields, 100+ stories, 70+ tests ✅
Week 4 (2026-08-20 → 2026-08-26)
├─ Step 2.1: Create 10 Pinia store modules (Mon-Tue)
├─ Step 2.2: Setup OpenAPI SDK + API client (Wed)
├─ Step 2.3: Implement MSW + integration tests (Thu)
├─ Step 2.4: Add E2E test scenarios (Fri)
└─ Deliverable: Pinia stores, API client, 100+ tests ✅
Next: Phase 3 (Domain Fields, Week 5-6)
```
---
**Status**: 🚀 Phase 2 Started (2026-08-12)
**Step 1 Progress**: 5/12 Typed Fields (42%)
**Timeline**: 2 weeks (2026-08-12 → 2026-08-26)