@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.
@@ -0,0 +1,566 @@
1
+ # @finema/finework-layer - LLM Documentation Guide
2
+
3
+ ## 📋 Overview
4
+
5
+ `@finema/finework-layer` is a Nuxt Layer providing reusable components, composables, layouts, and utilities for Finework applications. This layer extends `@finema/core` and provides enterprise-level features for building internal tools.
6
+
7
+ **Version:** 0.2.50
8
+ **Framework:** Nuxt 4.x
9
+ **UI Library:** @nuxt/ui (Nuxt UI v3)
10
+ **Package Manager:** pnpm/bun
11
+
12
+ ---
13
+
14
+ ## 🏗️ Project Structure
15
+
16
+ ```
17
+ finework-frontend-layer/
18
+ ├── app/
19
+ │ ├── components/ # Reusable Vue components
20
+ │ │ ├── Button/ # Button variants
21
+ │ │ ├── Layout/ # Layout components (Admin, User)
22
+ │ │ ├── InfoItemList.vue
23
+ │ │ └── StatusBox.vue
24
+ │ ├── composables/ # Vue composables
25
+ │ │ ├── useAuth.ts # Authentication logic
26
+ │ │ └── useRequestOptions.ts
27
+ │ ├── constants/ # Constants and configurations
28
+ │ │ └── routes.ts # Route definitions
29
+ │ ├── middleware/ # Route middleware
30
+ │ │ ├── auth.ts # Authentication guard
31
+ │ │ ├── permissions.ts # Permission-based access
32
+ │ │ ├── guest.ts # Guest-only routes
33
+ │ │ └── common.ts # Common middleware
34
+ │ ├── assets/css/ # Global styles
35
+ │ └── app.config.ts # App configuration
36
+ ├── .playground/ # Development playground
37
+ ├── nuxt.config.ts # Nuxt layer configuration
38
+ └── package.json
39
+ ```
40
+
41
+ ---
42
+
43
+ ## 🎯 Core Concepts
44
+
45
+ ### 1. **Nuxt Layer Architecture**
46
+
47
+ This is a **Nuxt Layer**, not a standalone application. It's designed to be extended by other Nuxt projects:
48
+
49
+ ```typescript
50
+ // In consuming project's nuxt.config.ts
51
+ export default defineNuxtConfig({
52
+ extends: ['@finema/finework-layer']
53
+ })
54
+ ```
55
+
56
+ ### 2. **Auto-imports**
57
+
58
+ The layer auto-imports from these directories:
59
+ - `./constants` - Route definitions, enums
60
+ - `./loaders` - Data loaders
61
+ - `./helpers` - Utility functions
62
+ - `./types` - TypeScript types
63
+
64
+ ### 3. **Dependency Chain**
65
+
66
+ ```
67
+ Your App → @finema/finework-layer → @finema/core → @nuxt/ui
68
+ ```
69
+
70
+ ---
71
+
72
+ ## 🔐 Authentication System
73
+
74
+ ### useAuth Composable
75
+
76
+ The `useAuth()` composable provides complete authentication functionality:
77
+
78
+ ```typescript
79
+ const auth = useAuth()
80
+
81
+ // Properties
82
+ auth.token // Cookie-based auth token
83
+ auth.isAuthenticated // Computed boolean
84
+ auth.me.value // Current user object (IUser)
85
+
86
+ // Methods
87
+ auth.loginSlack() // Slack OAuth login
88
+ auth.loginMs() // Microsoft OAuth login
89
+ auth.fetchMe.run() // Fetch current user
90
+ auth.updateMe.run() // Update user profile
91
+ auth.hasPermission(module, ...permissions) // Check permissions
92
+ auth.isSuperAdmin // Check if super admin
93
+ auth.menusNavbar // Navigation menu items
94
+ ```
95
+
96
+ ### User Interface
97
+
98
+ ```typescript
99
+ interface IUser {
100
+ id: string
101
+ email: string
102
+ full_name: string
103
+ display_name: string
104
+ position: string
105
+ team: ITeam
106
+ team_code: string
107
+ avatar_url: string
108
+ company: string
109
+ access_level: IUserAccessLevel
110
+ is_active: boolean
111
+ joined_date: string
112
+ slack_id: string
113
+ created_at: string
114
+ updated_at: string
115
+ }
116
+
117
+ interface IUserAccessLevel {
118
+ used_id: string
119
+ pmo: Permission.USER | Permission.ADMIN | Permission.SUPER
120
+ clockin: Permission.USER | Permission.ADMIN
121
+ timesheet: Permission.USER | Permission.ADMIN
122
+ setting: Permission.USER | Permission.SUPER
123
+ }
124
+
125
+ enum Permission {
126
+ USER = 'USER',
127
+ ADMIN = 'ADMIN',
128
+ SUPER = 'SUPER',
129
+ NONE = 'NONE'
130
+ }
131
+
132
+ enum UserModule {
133
+ CHECKIN = 'clockin',
134
+ PMO = 'pmo',
135
+ TIMESHEET = 'timesheet',
136
+ SETTING = 'setting'
137
+ }
138
+ ```
139
+
140
+ ### Permission Checking
141
+
142
+ ```typescript
143
+ // Check if user has permission
144
+ if (auth.hasPermission(UserModule.PMO, Permission.ADMIN, Permission.SUPER)) {
145
+ // User has PMO admin or super permission
146
+ }
147
+
148
+ // In route meta
149
+ definePageMeta({
150
+ middleware: ['auth', 'permissions'],
151
+ accessGuard: {
152
+ permissions: ['pmo:ADMIN', 'pmo:SUPER'],
153
+ redirectTo: '/unauthorized'
154
+ }
155
+ })
156
+ ```
157
+
158
+ ---
159
+
160
+ ## 🛣️ Routing & Middleware
161
+
162
+ ### Route Constants
163
+
164
+ All routes are defined in `app/constants/routes.ts`:
165
+
166
+ ```typescript
167
+ import { routes } from '#imports'
168
+
169
+ // Usage
170
+ navigateTo(routes.home.to)
171
+ navigateTo(routes.pmo.project.projects.to)
172
+ ```
173
+
174
+ ### Available Middleware
175
+
176
+ 1. **auth.ts** - Requires authentication
177
+ 2. **guest.ts** - Guest-only (redirects authenticated users)
178
+ 3. **permissions.ts** - Permission-based access control
179
+ 4. **common.ts** - Common logic (user fetching)
180
+
181
+ ```typescript
182
+ // Page with auth + permissions
183
+ definePageMeta({
184
+ middleware: ['auth', 'permissions'],
185
+ accessGuard: {
186
+ permissions: ['clockin:ADMIN'],
187
+ redirectTo: '/unauthorized'
188
+ }
189
+ })
190
+ ```
191
+
192
+ ---
193
+
194
+ ## 🎨 Components
195
+
196
+ ### 1. StatusBox
197
+
198
+ Handles loading, error, and empty states:
199
+
200
+ ```vue
201
+ <template>
202
+ <StatusBox :status="loader.status.value" :data="loader.data.value">
203
+ <template #default="{ data }">
204
+ <!-- Your content with data -->
205
+ <div>{{ data.name }}</div>
206
+ </template>
207
+ </StatusBox>
208
+ </template>
209
+
210
+ <script setup lang="ts">
211
+ const loader = useObjectLoader<MyData>({
212
+ method: 'GET',
213
+ url: '/api/data',
214
+ getRequestOptions: useRequestOptions().auth
215
+ })
216
+
217
+ onMounted(() => loader.run())
218
+ </script>
219
+ ```
220
+
221
+ ### 2. InfoItemList
222
+
223
+ Display key-value information lists:
224
+
225
+ ```vue
226
+ <template>
227
+ <InfoItemList
228
+ :items="[
229
+ { label: 'Name', value: user.full_name },
230
+ { label: 'Email', value: user.email },
231
+ { label: 'Position', value: user.position },
232
+ { label: 'Active', value: user.is_active, type: 'boolean' },
233
+ {
234
+ label: 'Description',
235
+ value: longText,
236
+ max: 100 // Truncate with "show more"
237
+ }
238
+ ]"
239
+ :vertical="false"
240
+ :inline="false"
241
+ />
242
+ </template>
243
+ ```
244
+
245
+ **Props:**
246
+ - `items` - Array of info items
247
+ - `vertical` - Stack items vertically (default: false = 2 columns)
248
+ - `inline` - Display label and value inline (default: false)
249
+ - `customClass` - Additional CSS classes
250
+
251
+ **Item Types:**
252
+ - `text` (default)
253
+ - `number`
254
+ - `currency`
255
+ - `date`
256
+ - `date_time`
257
+ - `boolean` - Shows checkbox
258
+
259
+ ### 3. Button Components
260
+
261
+ #### ActionIcon
262
+
263
+ ```vue
264
+ <ButtonActionIcon
265
+ icon="ph:pencil-simple"
266
+ color="primary"
267
+ :to="`/edit/${id}`"
268
+ @click="handleEdit"
269
+ />
270
+ ```
271
+
272
+ #### Back Button
273
+
274
+ ```vue
275
+ <ButtonBack
276
+ label="กลับไปหน้าหลัก"
277
+ :to="routes.home.to"
278
+ />
279
+ ```
280
+
281
+ ---
282
+
283
+ ## 🎨 Layouts
284
+
285
+ ### Admin Layout
286
+
287
+ Full-featured admin layout with sidebar navigation:
288
+
289
+ ```vue
290
+ <template>
291
+ <LayoutAdmin
292
+ label="Admin Panel"
293
+ :items="navigationItems"
294
+ >
295
+ <!-- Your page content -->
296
+ </LayoutAdmin>
297
+ </template>
298
+
299
+ <script setup lang="ts">
300
+ import type { NavigationMenuItem } from '@nuxt/ui'
301
+
302
+ const navigationItems: NavigationMenuItem[] = [
303
+ {
304
+ label: 'Dashboard',
305
+ icon: 'i-heroicons-home',
306
+ to: '/admin/dashboard'
307
+ },
308
+ {
309
+ label: 'Users',
310
+ icon: 'i-heroicons-users',
311
+ children: [
312
+ { label: 'All Users', to: '/admin/users' },
313
+ { label: 'Add User', to: '/admin/users/new' }
314
+ ]
315
+ }
316
+ ]
317
+ </script>
318
+ ```
319
+
320
+ ### User Layout
321
+
322
+ Simple user-facing layout:
323
+
324
+ ```vue
325
+ <template>
326
+ <LayoutUser>
327
+ <!-- Your page content -->
328
+ </LayoutUser>
329
+ </template>
330
+ ```
331
+
332
+ ---
333
+
334
+ ## 🔧 Composables
335
+
336
+ ### useRequestOptions
337
+
338
+ Provides pre-configured Axios request options:
339
+
340
+ ```typescript
341
+ const { auth, base, mock, file } = useRequestOptions()
342
+
343
+ // Authenticated request
344
+ const loader = useObjectLoader({
345
+ method: 'GET',
346
+ url: '/api/protected',
347
+ getRequestOptions: auth // Adds Authorization header
348
+ })
349
+
350
+ // Public request
351
+ const publicLoader = useObjectLoader({
352
+ method: 'GET',
353
+ url: '/api/public',
354
+ getRequestOptions: base
355
+ })
356
+
357
+ // File upload
358
+ const fileLoader = useObjectLoader({
359
+ method: 'POST',
360
+ url: '/upload',
361
+ getRequestOptions: file
362
+ })
363
+ ```
364
+
365
+ ---
366
+
367
+ ## 📝 Best Practices for LLM Code Generation
368
+
369
+ ### 1. **Always Use Existing Patterns**
370
+
371
+ ✅ **DO:**
372
+ ```typescript
373
+ // Use existing composables
374
+ const auth = useAuth()
375
+ const { auth: authOptions } = useRequestOptions()
376
+
377
+ // Use existing components
378
+ <StatusBox :status="loader.status.value" :data="loader.data.value">
379
+ ```
380
+
381
+ ❌ **DON'T:**
382
+ ```typescript
383
+ // Don't create custom auth logic
384
+ const token = useCookie('my-token')
385
+ const user = ref(null)
386
+ ```
387
+
388
+ ### 2. **Follow Component Conventions**
389
+
390
+ ✅ **DO:**
391
+ ```vue
392
+ <script setup lang="ts">
393
+ // TypeScript with proper types
394
+ interface Props {
395
+ title: string
396
+ items: MyItem[]
397
+ }
398
+
399
+ const props = defineProps<Props>()
400
+ const emit = defineEmits<{
401
+ update: [value: string]
402
+ }>()
403
+ </script>
404
+ ```
405
+
406
+ ### 3. **Use Auto-imported Constants**
407
+
408
+ ```typescript
409
+ // These are auto-imported
410
+ import { routes, UserModule, Permission } from '#imports'
411
+
412
+ // Navigate using route constants
413
+ navigateTo(routes.pmo.project.projects.to)
414
+ ```
415
+
416
+ ### 4. **Leverage @finema/core**
417
+
418
+ This layer extends `@finema/core` which provides:
419
+ - `useObjectLoader` - Data fetching
420
+ - `useListLoader` - List/pagination
421
+ - `useForm` - Form handling with validation
422
+ - UI components from @nuxt/ui
423
+
424
+ ---
425
+
426
+ ## 🎯 Common Patterns
427
+
428
+ ### Pattern 1: Protected Page with Data Loading
429
+
430
+ ```vue
431
+ <template>
432
+ <LayoutAdmin label="Projects" :items="navItems">
433
+ <StatusBox :status="projects.status.value" :data="projects.data.value">
434
+ <template #default="{ data }">
435
+ <div v-for="project in data" :key="project.id">
436
+ {{ project.name }}
437
+ </div>
438
+ </template>
439
+ </StatusBox>
440
+ </LayoutAdmin>
441
+ </template>
442
+
443
+ <script setup lang="ts">
444
+ definePageMeta({
445
+ middleware: ['auth', 'permissions'],
446
+ accessGuard: {
447
+ permissions: ['pmo:USER', 'pmo:ADMIN']
448
+ }
449
+ })
450
+
451
+ const projects = useListLoader({
452
+ method: 'GET',
453
+ url: '/api/projects',
454
+ getRequestOptions: useRequestOptions().auth
455
+ })
456
+
457
+ onMounted(() => projects.run())
458
+ </script>
459
+ ```
460
+
461
+ ### Pattern 2: Form with Validation
462
+
463
+ ```typescript
464
+ import * as v from 'valibot'
465
+ import { toTypedSchema } from '@vee-validate/valibot'
466
+
467
+ const form = useForm({
468
+ validationSchema: toTypedSchema(
469
+ v.object({
470
+ name: v.pipe(v.string(), v.minLength(3)),
471
+ email: v.pipe(v.string(), v.email()),
472
+ status: v.optional(v.string(), '')
473
+ })
474
+ )
475
+ })
476
+ ```
477
+
478
+ ---
479
+
480
+ ## 🚀 Development Workflow
481
+
482
+ ### Running the Playground
483
+
484
+ ```bash
485
+ pnpm dev # Start development server
486
+ pnpm build # Build for production
487
+ pnpm lint # Run ESLint
488
+ pnpm lint:fix # Fix linting issues
489
+ ```
490
+
491
+ ### Creating New Components
492
+
493
+ 1. Add to `app/components/`
494
+ 2. Use TypeScript with proper types
495
+ 3. Follow existing naming conventions
496
+ 4. Auto-imported, no need to import manually
497
+
498
+ ### Adding New Routes
499
+
500
+ 1. Define in `app/constants/routes.ts`
501
+ 2. Add middleware if needed
502
+ 3. Use in components via `routes.your.route.to`
503
+
504
+ ---
505
+
506
+ ## 📚 Additional Resources
507
+
508
+ - **Nuxt UI Docs:** https://ui.nuxt.com
509
+ - **Nuxt 3 Docs:** https://nuxt.com
510
+ - **@finema/core:** Internal package (check documentation)
511
+
512
+ ---
513
+
514
+ ## ⚠️ Important Notes for LLM
515
+
516
+ 1. **This is a Nuxt Layer** - Not a standalone app
517
+ 2. **Auto-imports are enabled** - No need to import components, composables, or constants
518
+ 3. **TypeScript is required** - Always use proper types
519
+ 4. **Follow existing patterns** - Don't reinvent the wheel
520
+ 5. **Use @nuxt/ui components** - Button, Card, Modal, etc.
521
+ 6. **Respect permission system** - Always check permissions for protected features
522
+ 7. **Use route constants** - Never hardcode routes
523
+
524
+ ---
525
+
526
+ ## 🔍 Quick Reference
527
+
528
+ ### Most Used Imports (Auto-imported)
529
+
530
+ ```typescript
531
+ // Composables
532
+ useAuth()
533
+ useRequestOptions()
534
+ useApp()
535
+ useForm()
536
+ useObjectLoader()
537
+ useListLoader()
538
+
539
+ // Constants
540
+ routes
541
+ Permission
542
+ UserModule
543
+
544
+ // Components (no import needed)
545
+ <StatusBox />
546
+ <InfoItemList />
547
+ <ButtonActionIcon />
548
+ <ButtonBack />
549
+ <LayoutAdmin />
550
+ <LayoutUser />
551
+ ```
552
+
553
+ ### Environment Variables
554
+
555
+ ```typescript
556
+ const config = useRuntimeConfig()
557
+
558
+ config.public.baseAPI // API base URL
559
+ config.public.baseAPIMock // Mock API URL
560
+ ```
561
+
562
+ ---
563
+
564
+ **Last Updated:** 2025-11-07
565
+ **Maintained by:** Finema Team
566
+