@finema/finework-layer 0.2.49 → 0.2.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.playground/app/pages/layout-admin/test/[id]/index.vue +286 -0
- package/.playground/app/pages/layout-admin.vue +2 -2
- package/@finema finework-layer - LLM Documentation Guide.md +566 -0
- package/API_REFERENCE.md +780 -0
- package/ARCHITECTURE.md +592 -0
- package/CHANGELOG.md +8 -0
- package/COMPONENT_EXAMPLES.md +893 -0
- package/DOCUMENTATION_INDEX.md +354 -0
- package/EXAMPLES.md +597 -0
- package/QUICK_START.md +678 -0
- package/README.md +199 -33
- package/TROUBLESHOOTING.md +646 -0
- package/app/components/Button/Back.vue +1 -1
- package/app/components/Layout/Admin/Sidebar.vue +10 -3
- package/app/components/Layout/Admin/index.vue +20 -19
- package/package.json +1 -1
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,592 @@
|
|
|
1
|
+
# Architecture Documentation
|
|
2
|
+
|
|
3
|
+
## 🏛️ System Architecture
|
|
4
|
+
|
|
5
|
+
### Overview
|
|
6
|
+
|
|
7
|
+
`@finema/finework-layer` follows a **layered architecture** pattern, serving as a middle layer between the core UI library and application-specific implementations.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
┌─────────────────────────────────────────┐
|
|
11
|
+
│ Application Layer │
|
|
12
|
+
│ (Consuming Nuxt Projects) │
|
|
13
|
+
└─────────────────┬───────────────────────┘
|
|
14
|
+
│ extends
|
|
15
|
+
┌─────────────────▼───────────────────────┐
|
|
16
|
+
│ @finema/finework-layer │
|
|
17
|
+
│ • Components │
|
|
18
|
+
│ • Composables │
|
|
19
|
+
│ • Layouts │
|
|
20
|
+
│ • Middleware │
|
|
21
|
+
│ • Constants │
|
|
22
|
+
└─────────────────┬───────────────────────┘
|
|
23
|
+
│ extends
|
|
24
|
+
┌─────────────────▼───────────────────────┐
|
|
25
|
+
│ @finema/core │
|
|
26
|
+
│ • Base Components │
|
|
27
|
+
│ • Data Loaders │
|
|
28
|
+
│ • Form Utilities │
|
|
29
|
+
│ • Core Composables │
|
|
30
|
+
└─────────────────┬───────────────────────┘
|
|
31
|
+
│ uses
|
|
32
|
+
┌─────────────────▼───────────────────────┐
|
|
33
|
+
│ @nuxt/ui │
|
|
34
|
+
│ • UI Components │
|
|
35
|
+
│ • Design System │
|
|
36
|
+
│ • Theming │
|
|
37
|
+
└─────────────────────────────────────────┘
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 📦 Module Structure
|
|
43
|
+
|
|
44
|
+
### 1. Components Layer
|
|
45
|
+
|
|
46
|
+
**Purpose:** Reusable UI components specific to Finework applications
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
app/components/
|
|
50
|
+
├── Button/
|
|
51
|
+
│ ├── ActionIcon.vue # Icon-only action buttons
|
|
52
|
+
│ └── Back.vue # Back navigation button
|
|
53
|
+
├── Layout/
|
|
54
|
+
│ ├── Admin/
|
|
55
|
+
│ │ ├── index.vue # Main admin layout
|
|
56
|
+
│ │ └── Sidebar.vue # Admin sidebar navigation
|
|
57
|
+
│ ├── User/
|
|
58
|
+
│ │ └── index.vue # User-facing layout
|
|
59
|
+
│ └── Apps.vue # App switcher popover
|
|
60
|
+
├── InfoItemList.vue # Key-value display component
|
|
61
|
+
└── StatusBox.vue # Loading/error/empty states
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Design Principles:**
|
|
65
|
+
- **Composition over Inheritance:** Components compose smaller components
|
|
66
|
+
- **Single Responsibility:** Each component has one clear purpose
|
|
67
|
+
- **Type Safety:** All props and emits are typed
|
|
68
|
+
- **Accessibility:** ARIA labels and keyboard navigation
|
|
69
|
+
|
|
70
|
+
### 2. Composables Layer
|
|
71
|
+
|
|
72
|
+
**Purpose:** Reusable business logic and state management
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
app/composables/
|
|
76
|
+
├── useAuth.ts # Authentication & authorization
|
|
77
|
+
└── useRequestOptions.ts # HTTP request configuration
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Key Patterns:**
|
|
81
|
+
- **Singleton Stores:** Using Pinia for shared state (e.g., `auth.me`)
|
|
82
|
+
- **Computed Properties:** Reactive derived state
|
|
83
|
+
- **Side Effects:** Watchers for state synchronization
|
|
84
|
+
|
|
85
|
+
### 3. Middleware Layer
|
|
86
|
+
|
|
87
|
+
**Purpose:** Route-level guards and logic
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
app/middleware/
|
|
91
|
+
├── auth.ts # Authentication guard
|
|
92
|
+
├── permissions.ts # Permission-based access
|
|
93
|
+
├── guest.ts # Guest-only routes
|
|
94
|
+
└── common.ts # Common pre-route logic
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Execution Order:**
|
|
98
|
+
1. `common.ts` - Always runs first
|
|
99
|
+
2. `auth.ts` - Checks authentication
|
|
100
|
+
3. `permissions.ts` - Validates permissions
|
|
101
|
+
4. `guest.ts` - Redirects authenticated users
|
|
102
|
+
|
|
103
|
+
### 4. Constants Layer
|
|
104
|
+
|
|
105
|
+
**Purpose:** Centralized configuration and constants
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
app/constants/
|
|
109
|
+
└── routes.ts # Route definitions
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Benefits:**
|
|
113
|
+
- Type-safe route references
|
|
114
|
+
- Single source of truth
|
|
115
|
+
- Easy refactoring
|
|
116
|
+
- Auto-completion support
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 🔄 Data Flow Architecture
|
|
121
|
+
|
|
122
|
+
### Authentication Flow
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
┌──────────────┐
|
|
126
|
+
│ Browser │
|
|
127
|
+
└──────┬───────┘
|
|
128
|
+
│ 1. Navigate to protected route
|
|
129
|
+
▼
|
|
130
|
+
┌──────────────────────┐
|
|
131
|
+
│ Middleware Chain │
|
|
132
|
+
│ ├─ common.ts │
|
|
133
|
+
│ ├─ auth.ts │
|
|
134
|
+
│ └─ permissions.ts │
|
|
135
|
+
└──────┬───────────────┘
|
|
136
|
+
│ 2. Check token cookie
|
|
137
|
+
▼
|
|
138
|
+
┌──────────────────────┐
|
|
139
|
+
│ useAuth() │
|
|
140
|
+
│ ├─ token │
|
|
141
|
+
│ ├─ me (store) │
|
|
142
|
+
│ └─ fetchMe() │
|
|
143
|
+
└──────┬───────────────┘
|
|
144
|
+
│ 3. Fetch user if needed
|
|
145
|
+
▼
|
|
146
|
+
┌──────────────────────┐
|
|
147
|
+
│ API Request │
|
|
148
|
+
│ GET /me │
|
|
149
|
+
│ Authorization: ... │
|
|
150
|
+
└──────┬───────────────┘
|
|
151
|
+
│ 4. Update store
|
|
152
|
+
▼
|
|
153
|
+
┌──────────────────────┐
|
|
154
|
+
│ Pinia Store │
|
|
155
|
+
│ auth.me.value │
|
|
156
|
+
└──────┬───────────────┘
|
|
157
|
+
│ 5. Render page
|
|
158
|
+
▼
|
|
159
|
+
┌──────────────────────┐
|
|
160
|
+
│ Page Component │
|
|
161
|
+
└──────────────────────┘
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Data Loading Flow
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
┌──────────────┐
|
|
168
|
+
│ Component │
|
|
169
|
+
│ onMounted() │
|
|
170
|
+
└──────┬───────┘
|
|
171
|
+
│ 1. Call loader.run()
|
|
172
|
+
▼
|
|
173
|
+
┌──────────────────────┐
|
|
174
|
+
│ useObjectLoader │
|
|
175
|
+
│ (from @finema/core) │
|
|
176
|
+
└──────┬───────────────┘
|
|
177
|
+
│ 2. Make HTTP request
|
|
178
|
+
▼
|
|
179
|
+
┌──────────────────────┐
|
|
180
|
+
│ useRequestOptions │
|
|
181
|
+
│ ├─ auth() │
|
|
182
|
+
│ ├─ base() │
|
|
183
|
+
│ └─ file() │
|
|
184
|
+
└──────┬───────────────┘
|
|
185
|
+
│ 3. Add headers/config
|
|
186
|
+
▼
|
|
187
|
+
┌──────────────────────┐
|
|
188
|
+
│ Axios Request │
|
|
189
|
+
└──────┬───────────────┘
|
|
190
|
+
│ 4. Response
|
|
191
|
+
▼
|
|
192
|
+
┌──────────────────────┐
|
|
193
|
+
│ Loader State │
|
|
194
|
+
│ ├─ status │
|
|
195
|
+
│ │ ├─ isLoading │
|
|
196
|
+
│ │ ├─ isSuccess │
|
|
197
|
+
│ │ └─ isError │
|
|
198
|
+
│ └─ data │
|
|
199
|
+
└──────┬───────────────┘
|
|
200
|
+
│ 5. Reactive update
|
|
201
|
+
▼
|
|
202
|
+
┌──────────────────────┐
|
|
203
|
+
│ StatusBox │
|
|
204
|
+
│ Shows appropriate │
|
|
205
|
+
│ state │
|
|
206
|
+
└──────────────────────┘
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 🎨 Component Architecture
|
|
212
|
+
|
|
213
|
+
### StatusBox Pattern
|
|
214
|
+
|
|
215
|
+
**Problem:** Every data-loading component needs to handle:
|
|
216
|
+
- Loading state
|
|
217
|
+
- Error state
|
|
218
|
+
- Empty state
|
|
219
|
+
- Success state
|
|
220
|
+
|
|
221
|
+
**Solution:** `StatusBox` component abstracts this logic
|
|
222
|
+
|
|
223
|
+
```vue
|
|
224
|
+
<StatusBox :status="loader.status.value" :data="loader.data.value">
|
|
225
|
+
<template #default="{ data }">
|
|
226
|
+
<!-- Only renders when data is successfully loaded -->
|
|
227
|
+
</template>
|
|
228
|
+
</StatusBox>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Benefits:**
|
|
232
|
+
- Consistent UX across all pages
|
|
233
|
+
- Reduced boilerplate
|
|
234
|
+
- Centralized error handling
|
|
235
|
+
- Easy to update globally
|
|
236
|
+
|
|
237
|
+
### Layout Pattern
|
|
238
|
+
|
|
239
|
+
**Problem:** Different user roles need different layouts
|
|
240
|
+
|
|
241
|
+
**Solution:** Composable layout components
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
LayoutAdmin
|
|
245
|
+
├─ Sidebar (collapsible)
|
|
246
|
+
├─ Header (user menu, apps)
|
|
247
|
+
└─ Main content area
|
|
248
|
+
|
|
249
|
+
LayoutUser
|
|
250
|
+
├─ Top navbar
|
|
251
|
+
├─ Breadcrumbs
|
|
252
|
+
└─ Main content area
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Features:**
|
|
256
|
+
- Responsive design
|
|
257
|
+
- Mobile-friendly
|
|
258
|
+
- Consistent navigation
|
|
259
|
+
- Role-based menus
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## 🔐 Security Architecture
|
|
264
|
+
|
|
265
|
+
### Authentication Layers
|
|
266
|
+
|
|
267
|
+
1. **Cookie-based Token Storage**
|
|
268
|
+
- HttpOnly cookie (set by backend)
|
|
269
|
+
- Secure flag in production
|
|
270
|
+
- SameSite protection
|
|
271
|
+
|
|
272
|
+
2. **Middleware Guards**
|
|
273
|
+
- Route-level protection
|
|
274
|
+
- Automatic redirects
|
|
275
|
+
- Token validation
|
|
276
|
+
|
|
277
|
+
3. **Permission System**
|
|
278
|
+
- Module-based permissions
|
|
279
|
+
- Role hierarchy (USER < ADMIN < SUPER)
|
|
280
|
+
- Fine-grained access control
|
|
281
|
+
|
|
282
|
+
### Permission Matrix
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
interface IUserAccessLevel {
|
|
286
|
+
pmo: Permission // PMO module access
|
|
287
|
+
clockin: Permission // Clock-in module access
|
|
288
|
+
timesheet: Permission // Timesheet module access
|
|
289
|
+
setting: Permission // Settings module access
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
enum Permission {
|
|
293
|
+
NONE = 'NONE', // No access
|
|
294
|
+
USER = 'USER', // Basic user access
|
|
295
|
+
ADMIN = 'ADMIN', // Admin access
|
|
296
|
+
SUPER = 'SUPER' // Super admin access
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Example Checks:**
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
// Single permission check
|
|
304
|
+
hasPermission(UserModule.PMO, Permission.ADMIN)
|
|
305
|
+
|
|
306
|
+
// Multiple permission check (OR logic)
|
|
307
|
+
hasPermission(UserModule.PMO, Permission.ADMIN, Permission.SUPER)
|
|
308
|
+
|
|
309
|
+
// Route-level guard
|
|
310
|
+
definePageMeta({
|
|
311
|
+
accessGuard: {
|
|
312
|
+
permissions: ['pmo:ADMIN', 'pmo:SUPER']
|
|
313
|
+
}
|
|
314
|
+
})
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## 🚀 Performance Optimizations
|
|
320
|
+
|
|
321
|
+
### 1. Auto-imports
|
|
322
|
+
|
|
323
|
+
**Configuration:**
|
|
324
|
+
```typescript
|
|
325
|
+
// nuxt.config.ts
|
|
326
|
+
imports: {
|
|
327
|
+
dirs: ['./constants', './loaders', './helpers', './types']
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Benefits:**
|
|
332
|
+
- Smaller bundle size (tree-shaking)
|
|
333
|
+
- Better DX (no import statements)
|
|
334
|
+
- Faster compilation
|
|
335
|
+
|
|
336
|
+
### 2. Component Auto-registration
|
|
337
|
+
|
|
338
|
+
All components in `app/components/` are automatically registered:
|
|
339
|
+
|
|
340
|
+
```vue
|
|
341
|
+
<!-- No import needed -->
|
|
342
|
+
<StatusBox />
|
|
343
|
+
<InfoItemList />
|
|
344
|
+
<ButtonActionIcon />
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### 3. Lazy Loading
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
// Lazy load heavy components
|
|
351
|
+
const HeavyChart = defineAsyncComponent(() =>
|
|
352
|
+
import('./components/HeavyChart.vue')
|
|
353
|
+
)
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### 4. State Caching
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
// useAuth caches user data for 1 minute
|
|
360
|
+
const isShouldFetch = () => {
|
|
361
|
+
if (!value.value || !timestamp.value) return true
|
|
362
|
+
return Date.now() - timestamp.value > 1000 * 60 * 1
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## 🧪 Testing Strategy
|
|
369
|
+
|
|
370
|
+
### Component Testing
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
import { mount } from '@nuxt/test-utils'
|
|
374
|
+
import StatusBox from '~/components/StatusBox.vue'
|
|
375
|
+
|
|
376
|
+
describe('StatusBox', () => {
|
|
377
|
+
it('shows loading state', () => {
|
|
378
|
+
const wrapper = mount(StatusBox, {
|
|
379
|
+
props: {
|
|
380
|
+
status: { isLoading: true },
|
|
381
|
+
data: null
|
|
382
|
+
}
|
|
383
|
+
})
|
|
384
|
+
expect(wrapper.find('Loader').exists()).toBe(true)
|
|
385
|
+
})
|
|
386
|
+
})
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Integration Testing
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
import { setup, $fetch } from '@nuxt/test-utils'
|
|
393
|
+
|
|
394
|
+
describe('Auth Flow', () => {
|
|
395
|
+
await setup({
|
|
396
|
+
// Test configuration
|
|
397
|
+
})
|
|
398
|
+
|
|
399
|
+
it('redirects unauthenticated users', async () => {
|
|
400
|
+
const response = await $fetch('/protected-route')
|
|
401
|
+
expect(response.redirected).toBe(true)
|
|
402
|
+
})
|
|
403
|
+
})
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## 📊 State Management
|
|
409
|
+
|
|
410
|
+
### Pinia Stores
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
// Defined inline in composables
|
|
414
|
+
const me = defineStore('auth.me', () => {
|
|
415
|
+
const value = ref<IUser | null>(null)
|
|
416
|
+
const timestamp = ref<number | null>(null)
|
|
417
|
+
|
|
418
|
+
const set = (user: IUser | null) => {
|
|
419
|
+
value.value = user
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return { value, set, timestamp }
|
|
423
|
+
})()
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
**Benefits:**
|
|
427
|
+
- Composition API style
|
|
428
|
+
- TypeScript support
|
|
429
|
+
- Devtools integration
|
|
430
|
+
- SSR-friendly
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## 🎯 Design Patterns
|
|
435
|
+
|
|
436
|
+
### 1. Composable Pattern
|
|
437
|
+
|
|
438
|
+
**Purpose:** Reusable stateful logic
|
|
439
|
+
|
|
440
|
+
```typescript
|
|
441
|
+
export const useAuth = () => {
|
|
442
|
+
// State
|
|
443
|
+
const token = useCookie('token')
|
|
444
|
+
|
|
445
|
+
// Computed
|
|
446
|
+
const isAuthenticated = computed(() => !!token.value)
|
|
447
|
+
|
|
448
|
+
// Methods
|
|
449
|
+
const login = () => { /* ... */ }
|
|
450
|
+
|
|
451
|
+
return { token, isAuthenticated, login }
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### 2. Provider Pattern
|
|
456
|
+
|
|
457
|
+
**Purpose:** Dependency injection
|
|
458
|
+
|
|
459
|
+
```typescript
|
|
460
|
+
export const useRequestOptions = () => {
|
|
461
|
+
const config = useRuntimeConfig()
|
|
462
|
+
|
|
463
|
+
const auth = () => ({
|
|
464
|
+
baseURL: config.public.baseAPI,
|
|
465
|
+
headers: {
|
|
466
|
+
Authorization: `Bearer ${useAuth().token.value}`
|
|
467
|
+
}
|
|
468
|
+
})
|
|
469
|
+
|
|
470
|
+
return { auth, base, mock, file }
|
|
471
|
+
}
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### 3. Slot Pattern
|
|
475
|
+
|
|
476
|
+
**Purpose:** Flexible component composition
|
|
477
|
+
|
|
478
|
+
```vue
|
|
479
|
+
<StatusBox :status="status" :data="data">
|
|
480
|
+
<template #default="{ data }">
|
|
481
|
+
<!-- Custom rendering with data -->
|
|
482
|
+
</template>
|
|
483
|
+
</StatusBox>
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### 4. Middleware Chain Pattern
|
|
487
|
+
|
|
488
|
+
**Purpose:** Sequential request processing
|
|
489
|
+
|
|
490
|
+
```typescript
|
|
491
|
+
// Middleware executes in order
|
|
492
|
+
export default defineNuxtConfig({
|
|
493
|
+
router: {
|
|
494
|
+
middleware: ['common', 'auth', 'permissions']
|
|
495
|
+
}
|
|
496
|
+
})
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
## 🔧 Configuration Management
|
|
502
|
+
|
|
503
|
+
### App Config
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
// app/app.config.ts
|
|
507
|
+
export default defineAppConfig({
|
|
508
|
+
core: {
|
|
509
|
+
is_thai_year: false,
|
|
510
|
+
date_format: 'dd MMM yyyy',
|
|
511
|
+
color: '#335AFF',
|
|
512
|
+
limit_per_page: 10,
|
|
513
|
+
locale: 'en'
|
|
514
|
+
},
|
|
515
|
+
ui: {
|
|
516
|
+
// Nuxt UI customization
|
|
517
|
+
}
|
|
518
|
+
})
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### Runtime Config
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
// Access in components
|
|
525
|
+
const config = useRuntimeConfig()
|
|
526
|
+
config.public.baseAPI
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
---
|
|
530
|
+
|
|
531
|
+
## 📈 Scalability Considerations
|
|
532
|
+
|
|
533
|
+
### 1. Module Federation
|
|
534
|
+
- Each feature can be a separate module
|
|
535
|
+
- Lazy load modules on demand
|
|
536
|
+
- Independent deployment possible
|
|
537
|
+
|
|
538
|
+
### 2. Code Splitting
|
|
539
|
+
- Route-based splitting (automatic)
|
|
540
|
+
- Component-based splitting (manual)
|
|
541
|
+
- Vendor chunk optimization
|
|
542
|
+
|
|
543
|
+
### 3. Caching Strategy
|
|
544
|
+
- User data cached for 1 minute
|
|
545
|
+
- Static assets cached indefinitely
|
|
546
|
+
- API responses cached per request
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
## 🔍 Debugging Guide
|
|
551
|
+
|
|
552
|
+
### Common Issues
|
|
553
|
+
|
|
554
|
+
1. **Auto-import not working**
|
|
555
|
+
- Check `nuxt.config.ts` imports configuration
|
|
556
|
+
- Restart dev server
|
|
557
|
+
- Check file location
|
|
558
|
+
|
|
559
|
+
2. **Middleware not executing**
|
|
560
|
+
- Check middleware order
|
|
561
|
+
- Verify route meta configuration
|
|
562
|
+
- Check return values
|
|
563
|
+
|
|
564
|
+
3. **Permission denied**
|
|
565
|
+
- Verify user access_level
|
|
566
|
+
- Check permission constants
|
|
567
|
+
- Review middleware logic
|
|
568
|
+
|
|
569
|
+
### Debug Tools
|
|
570
|
+
|
|
571
|
+
```typescript
|
|
572
|
+
// Enable verbose logging
|
|
573
|
+
const auth = useAuth()
|
|
574
|
+
console.log('User:', auth.me.value)
|
|
575
|
+
console.log('Permissions:', auth.me.value?.access_level)
|
|
576
|
+
console.log('Has PMO Admin:', auth.hasPermission(UserModule.PMO, Permission.ADMIN))
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
## 📚 Further Reading
|
|
582
|
+
|
|
583
|
+
- [Nuxt Layers Documentation](https://nuxt.com/docs/guide/going-further/layers)
|
|
584
|
+
- [Nuxt UI Documentation](https://ui.nuxt.com)
|
|
585
|
+
- [Vue 3 Composition API](https://vuejs.org/guide/extras/composition-api-faq.html)
|
|
586
|
+
- [Pinia Documentation](https://pinia.vuejs.org)
|
|
587
|
+
|
|
588
|
+
---
|
|
589
|
+
|
|
590
|
+
**Last Updated:** 2025-11-07
|
|
591
|
+
**Version:** 0.2.50
|
|
592
|
+
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.51](https://gitlab.finema.co/finema/finework/finework-frontend-layer/compare/0.2.50...0.2.51) (2025-11-11)
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* update sidebar navigation and breadcrumb rootpath ([1cbdcf1](https://gitlab.finema.co/finema/finework/finework-frontend-layer/commit/1cbdcf135c35bff66c70a71831193255ea5d302b))
|
|
8
|
+
|
|
9
|
+
## [0.2.50](https://gitlab.finema.co/finema/finework/finework-frontend-layer/compare/0.2.49...0.2.50) (2025-11-07)
|
|
10
|
+
|
|
3
11
|
## [0.2.49](https://gitlab.finema.co/finema/finework/finework-frontend-layer/compare/0.2.48...0.2.49) (2025-11-07)
|
|
4
12
|
|
|
5
13
|
### Bug Fixes
|