@goplusvn/core 0.1.59 → 0.1.61
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/PLATFORM.md +18 -0
- package/bin/goerp-init.mjs +141 -0
- package/package.json +4 -4
- package/src/cron/db-cron-manager.ts +3 -3
- package/src/cron/index.ts +2 -2
- package/src/{infrastructure/cron/cron-manager.ts → cron/simple-cron-job.ts} +1 -1
- package/src/crud/lib/mutation-builder.ts +105 -0
- package/src/crud/lib/query-builder.ts +119 -0
- package/src/crud/server-service.ts +35 -163
- package/src/infrastructure/__tests__/architecture-verification.spec.ts +13 -97
- package/src/infrastructure/index.ts +4 -7
- package/src/ui/management/index.ts +3 -2
- package/templates/starter-app/.dockerignore +41 -0
- package/templates/starter-app/.env.example +25 -0
- package/templates/starter-app/AGENTS.md +52 -0
- package/templates/starter-app/Dockerfile +74 -0
- package/templates/starter-app/README.md +141 -0
- package/templates/starter-app/gitignore +9 -0
- package/templates/starter-app/next.config.mjs +50 -0
- package/templates/starter-app/package.json +55 -0
- package/templates/starter-app/postcss.config.mjs +5 -0
- package/templates/starter-app/prisma/migrations/20260801000000_init/migration.sql +504 -0
- package/templates/starter-app/prisma/migrations/20260801091814_goerp_audit_logs_0001_init/migration.sql +33 -0
- package/templates/starter-app/prisma/migrations/20260801091815_goerp_background_tasks_0001_init/migration.sql +23 -0
- package/templates/starter-app/prisma/migrations/20260801091816_goerp_error_logs_0001_init/migration.sql +32 -0
- package/templates/starter-app/prisma/migrations/20260801091817_goerp_notifications_0001_init/migration.sql +59 -0
- package/templates/starter-app/prisma/migrations/20260801091818_goerp_system_jobs_0001_init/migration.sql +47 -0
- package/templates/starter-app/prisma/schema/auth.prisma +87 -0
- package/templates/starter-app/prisma/schema/domain.prisma +24 -0
- package/templates/starter-app/prisma/schema/goerp-audit-logs.prisma +23 -0
- package/templates/starter-app/prisma/schema/goerp-background-tasks.prisma +25 -0
- package/templates/starter-app/prisma/schema/goerp-error-logs.prisma +31 -0
- package/templates/starter-app/prisma/schema/goerp-notifications.prisma +49 -0
- package/templates/starter-app/prisma/schema/goerp-system-jobs.prisma +45 -0
- package/templates/starter-app/prisma/schema/organization.prisma +31 -0
- package/templates/starter-app/prisma/schema/rbac.prisma +100 -0
- package/templates/starter-app/prisma/schema/schema.prisma +8 -0
- package/templates/starter-app/prisma/schema/system.prisma +22 -0
- package/templates/starter-app/prisma/seed.ts +127 -0
- package/templates/starter-app/prisma.config.ts +20 -0
- package/templates/starter-app/public/.gitkeep +2 -0
- package/templates/starter-app/scripts/rbac-sync.ts +235 -0
- package/templates/starter-app/src/__tests__/architecture.test.ts +151 -0
- package/templates/starter-app/src/app/[lang]/(main)/admin/system/audit/page.tsx +24 -0
- package/templates/starter-app/src/app/[lang]/(main)/admin/system/error-logs/page.tsx +21 -0
- package/templates/starter-app/src/app/[lang]/(main)/admin/system/jobs/page.tsx +18 -0
- package/templates/starter-app/src/app/[lang]/(main)/admin/system/settings/page.tsx +22 -0
- package/templates/starter-app/src/app/[lang]/(main)/crud/[entity]/page.tsx +41 -0
- package/templates/starter-app/src/app/[lang]/(main)/layout.tsx +13 -0
- package/templates/starter-app/src/app/[lang]/(main)/notifications/page.tsx +13 -0
- package/templates/starter-app/src/app/[lang]/(main)/page.tsx +130 -0
- package/templates/starter-app/src/app/[lang]/(main)/roles/[id]/edit/page.tsx +60 -0
- package/templates/starter-app/src/app/[lang]/(main)/roles/new/page.tsx +41 -0
- package/templates/starter-app/src/app/[lang]/(main)/roles/page.tsx +48 -0
- package/templates/starter-app/src/app/[lang]/(main)/tasks/page.tsx +13 -0
- package/templates/starter-app/src/app/[lang]/(plain)/layout.tsx +10 -0
- package/templates/starter-app/src/app/[lang]/(plain)/sign-in/page.tsx +39 -0
- package/templates/starter-app/src/app/[lang]/layout.tsx +21 -0
- package/templates/starter-app/src/app/api/admin/system/audit/route.ts +60 -0
- package/templates/starter-app/src/app/api/admin/system/jobs/[name]/history/route.ts +39 -0
- package/templates/starter-app/src/app/api/admin/system/jobs/route.ts +96 -0
- package/templates/starter-app/src/app/api/admin/system/settings/all/route.ts +17 -0
- package/templates/starter-app/src/app/api/admin/system/settings/create/route.ts +19 -0
- package/templates/starter-app/src/app/api/admin/system/settings/delete/route.ts +20 -0
- package/templates/starter-app/src/app/api/admin/system/settings/route.ts +49 -0
- package/templates/starter-app/src/app/api/admin/system/settings/toggle-status/route.ts +28 -0
- package/templates/starter-app/src/app/api/admin/system/settings/update/route.ts +24 -0
- package/templates/starter-app/src/app/api/admin/system/settings/update-full/route.ts +23 -0
- package/templates/starter-app/src/app/api/better-auth/[...all]/route.ts +13 -0
- package/templates/starter-app/src/app/api/crud/[entity]/[id]/route.ts +13 -0
- package/templates/starter-app/src/app/api/crud/[entity]/route.ts +14 -0
- package/templates/starter-app/src/app/api/error-logs/[id]/route.ts +23 -0
- package/templates/starter-app/src/app/api/error-logs/route.ts +124 -0
- package/templates/starter-app/src/app/api/files/[...key]/route.ts +25 -0
- package/templates/starter-app/src/app/api/notifications/read/route.ts +29 -0
- package/templates/starter-app/src/app/api/notifications/route.ts +26 -0
- package/templates/starter-app/src/app/api/notifications/unread-count/route.ts +14 -0
- package/templates/starter-app/src/app/api/rbac/permissions-version/route.ts +11 -0
- package/templates/starter-app/src/app/api/roles/[id]/route.ts +14 -0
- package/templates/starter-app/src/app/api/roles/route.ts +18 -0
- package/templates/starter-app/src/app/api/tasks/[id]/download/route.ts +52 -0
- package/templates/starter-app/src/app/api/tasks/route.ts +37 -0
- package/templates/starter-app/src/app/api/upload/route.ts +15 -0
- package/templates/starter-app/src/app/globals.css +15 -0
- package/templates/starter-app/src/app/layout.tsx +16 -0
- package/templates/starter-app/src/app/page.tsx +8 -0
- package/templates/starter-app/src/components/layout/main-layout-wrapper.tsx +30 -0
- package/templates/starter-app/src/configs/entities/department.config.ts +24 -0
- package/templates/starter-app/src/configs/entities/index.ts +13 -0
- package/templates/starter-app/src/configs/i18n.ts +12 -0
- package/templates/starter-app/src/configs/permissions/index.ts +45 -0
- package/templates/starter-app/src/configs/permissions/master-data.permissions.ts +31 -0
- package/templates/starter-app/src/configs/permissions/system.permissions.ts +131 -0
- package/templates/starter-app/src/configs/permissions/types.ts +63 -0
- package/templates/starter-app/src/configs/tenant.ts +18 -0
- package/templates/starter-app/src/data/dictionary.ts +8 -0
- package/templates/starter-app/src/data/navigations.ts +61 -0
- package/templates/starter-app/src/instrumentation.ts +105 -0
- package/templates/starter-app/src/lib/api-handler.ts +157 -0
- package/templates/starter-app/src/lib/auth-client.ts +57 -0
- package/templates/starter-app/src/lib/auth.ts +62 -0
- package/templates/starter-app/src/lib/better-auth.ts +107 -0
- package/templates/starter-app/src/lib/branch-scope.ts +53 -0
- package/templates/starter-app/src/lib/cron/db-cron-manager.ts +42 -0
- package/templates/starter-app/src/lib/crud/index.ts +13 -0
- package/templates/starter-app/src/lib/errors/app-error.ts +2 -0
- package/templates/starter-app/src/lib/errors/error-handler.ts +5 -0
- package/templates/starter-app/src/lib/errors/log-server-error.ts +15 -0
- package/templates/starter-app/src/lib/errors/server-error.ts +11 -0
- package/templates/starter-app/src/lib/logger.ts +30 -0
- package/templates/starter-app/src/lib/page-guard.ts +35 -0
- package/templates/starter-app/src/lib/prisma.ts +80 -0
- package/templates/starter-app/src/lib/rbac/access.ts +87 -0
- package/templates/starter-app/src/lib/storage.ts +28 -0
- package/templates/starter-app/src/providers/index.tsx +54 -0
- package/templates/starter-app/src/providers/mode-provider.tsx +31 -0
- package/templates/starter-app/src/providers/theme-provider.tsx +21 -0
- package/templates/starter-app/src/proxy.ts +45 -0
- package/templates/starter-app/src/server/services/notification-service.ts +31 -0
- package/templates/starter-app/src/server/services/system-config-service.ts +163 -0
- package/templates/starter-app/src/server/tasks/handlers/export-departments.ts +58 -0
- package/templates/starter-app/src/server/tasks/index.ts +16 -0
- package/templates/starter-app/src/server/tasks/task-runner.ts +40 -0
- package/templates/starter-app/src/types/session.ts +29 -0
- package/templates/starter-app/tsconfig.json +47 -0
- package/templates/starter-app/vitest.config.ts +17 -0
- package/src/infrastructure/cron/index.ts +0 -6
- package/src/infrastructure/event-bus/event-bus.ts +0 -145
- package/src/infrastructure/event-bus/index.ts +0 -2
- package/src/infrastructure/event-bus/types.ts +0 -22
- package/src/infrastructure/lock/decorators.ts +0 -67
- package/src/infrastructure/lock/index.ts +0 -2
- package/src/infrastructure/lock/lock-manager.ts +0 -33
- package/src/plugin/apps-registry.ts +0 -97
- package/src/plugin/index.ts +0 -5
- package/src/plugin/types.ts +0 -41
- package/src/ui/management/audit-log-page.tsx +0 -14
- package/src/ui/management/job-management.tsx +0 -308
- package/src/workflow/activity-timeline.tsx +0 -412
- package/src/workflow/approval-workflow.tsx +0 -31
- package/src/workflow/index.ts +0 -2
- /package/src/{infrastructure/cron → cron}/types.ts +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# GoERP starter app
|
|
2
|
+
|
|
3
|
+
Bộ khung **chạy được ngay** cho một ứng dụng ERP trên `@goerp/core`: Next.js 16 +
|
|
4
|
+
Prisma 7 + Better Auth. Cài, seed, `pnpm dev` là có đăng nhập thật, phân quyền,
|
|
5
|
+
CRUD, nhật ký lỗi, nhật ký hoạt động, thông báo, tác vụ nền và tác vụ định kỳ —
|
|
6
|
+
tất cả lấy từ core, không phải mã copy.
|
|
7
|
+
|
|
8
|
+
Đây là **điểm xuất phát** của một app mới, không phải bản demo để đọc.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Bắt đầu
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# tạo app mới (không cần clone goerp-core):
|
|
16
|
+
npx -p @goplusvn/core goerp-init my-app --port 3010 && cd my-app
|
|
17
|
+
# trong repo goerp-core thì dùng: pnpm init-app my-app --dir ../my-app
|
|
18
|
+
|
|
19
|
+
pnpm install # postinstall tự chạy `prisma generate`
|
|
20
|
+
# `.env` đã sinh sẵn lúc init (BETTER_AUTH_SECRET ngẫu nhiên) — sửa DATABASE_URL
|
|
21
|
+
# cho trỏ đúng Postgres của bạn
|
|
22
|
+
|
|
23
|
+
pnpm prisma:deploy # dựng toàn bộ bảng (migration `_init` có sẵn)
|
|
24
|
+
pnpm seed # vai trò + tài khoản admin + dữ liệu mẫu
|
|
25
|
+
pnpm rbac-sync # nạp resource/action/quyền từ registry
|
|
26
|
+
pnpm dev # http://localhost:3010
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
> ⚠️ **Thứ tự `seed` → `rbac-sync` không đảo được.** `rbac-sync` chỉ cấp quyền
|
|
30
|
+
> mặc định cho resource nó vừa TẠO MỚI (để không đè chỉnh sửa của quản trị
|
|
31
|
+
> viên trên production). Chạy nó trước `seed` thì vai trò chưa tồn tại, grant
|
|
32
|
+
> bị bỏ, và lần chạy sau resource không còn "mới" nên im lặng bỏ qua mãi —
|
|
33
|
+
> app dựng xong mà không ai vào được màn hình nào. Lỡ đảo rồi thì chữa bằng
|
|
34
|
+
> `pnpm rbac-sync --force-grants`.
|
|
35
|
+
>
|
|
36
|
+
> ⚠️ Đừng dùng `prisma migrate dev` / `db push` / `migrate reset` — chúng có thể
|
|
37
|
+
> reset sạch DB khi phát hiện drift. Template đã có sẵn migration khởi tạo nên
|
|
38
|
+
> `pnpm prisma:deploy` là lệnh duy nhất cần, cả lúc dựng lẫn về sau.
|
|
39
|
+
|
|
40
|
+
Chỉ muốn xem giao diện, chưa có DB? Đặt `BYPASS_AUTH=1` trong `.env` — app boot
|
|
41
|
+
với phiên admin giả, bỏ qua đăng nhập. Màn hình nào đọc DB thì vẫn cần Postgres.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Có sẵn những gì
|
|
46
|
+
|
|
47
|
+
| Đường dẫn | Nội dung |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| `/sign-in` | Đăng nhập thật (Better Auth, mật khẩu bcrypt trên bảng `Account`). |
|
|
50
|
+
| `/vi` | Trang chủ mẫu. |
|
|
51
|
+
| `/vi/crud/departments` | CRUD đầy đủ (bảng + form + lọc + nhập/xuất) sinh từ **một** `EntityConfig`. |
|
|
52
|
+
| `/vi/roles` | Vai trò + ma trận quyền. Trang của core, dữ liệu do app nạp. |
|
|
53
|
+
| `/vi/admin/system/settings` | Cấu hình hệ thống (key-value + nhóm cấu hình có kiểu). |
|
|
54
|
+
| `/vi/admin/system/audit` | Nhật ký thay đổi dữ liệu (extension Prisma tự ghi). |
|
|
55
|
+
| `/vi/admin/system/error-logs` | Nhật ký lỗi server kèm stack. |
|
|
56
|
+
| `/vi/admin/system/jobs` | Tác vụ định kỳ: bật/tắt, chạy tay, lịch sử chạy. |
|
|
57
|
+
| `/vi/notifications` | Hộp thư của người dùng + chuông trên thanh tiêu đề. |
|
|
58
|
+
| `/vi/tasks` | Tác vụ nền của người dùng + tải file kết quả. |
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Bản đồ mã nguồn
|
|
63
|
+
|
|
64
|
+
| File | Vai trò |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `src/proxy.ts` | **Cổng xác thực default-deny**. Quên gác một route mới cũng không thành lỗ hổng. |
|
|
67
|
+
| `src/lib/api-handler.ts` | **Cổng của tầng API**: session → quyền → audit context → ghi error_logs. Mọi route đi qua đây. |
|
|
68
|
+
| `src/lib/page-guard.ts` | `requirePageAccess(lang, resource)` — gác quyền ở tầng TRANG. |
|
|
69
|
+
| `src/lib/prisma.ts` | Prisma client DUY NHẤT + audit extension + nối dây `SettingsService`. |
|
|
70
|
+
| `src/lib/auth.ts` / `src/lib/better-auth.ts` | `getSession()` — nguồn phiên duy nhất phía server; cấu hình Better Auth. |
|
|
71
|
+
| `src/lib/rbac/access.ts` | Nạp vai trò + quyền + chi nhánh của user trong MỘT truy vấn cho session. |
|
|
72
|
+
| `src/configs/permissions/` | **Permission Registry** — dữ liệu thuần, mỗi phân hệ một file. `pnpm rbac-sync` đồng bộ xuống DB. |
|
|
73
|
+
| `src/configs/entities/` | `EntityConfig` cho CRUD engine. Thêm entity = thêm một file + một dòng registry. |
|
|
74
|
+
| `src/lib/crud/` + `src/app/api/crud/[entity]/` | Backend CRUD generic của core; app chỉ tiêm `prisma` + map entity → model. |
|
|
75
|
+
| `src/data/navigations.ts` | Menu sidebar. `resource` của mỗi mục nối với RBAC để tự ẩn khi thiếu quyền. |
|
|
76
|
+
| `src/instrumentation.ts` | Boot: khởi động cron, thu hồi tác vụ treo, `onRequestError` → error_logs. |
|
|
77
|
+
| `src/server/tasks/` | Tác vụ nền: `configureTaskRunner` + handler mẫu (xuất CSV theo trang). |
|
|
78
|
+
| `src/server/services/` | Dịch vụ dùng chung cho route (thông báo, cấu hình hệ thống). |
|
|
79
|
+
| `src/__tests__/architecture.test.ts` | **Ratchet** kiến trúc — mỗi kiểm tra là một lỗi im lặng đã từng mất thời gian. |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Thêm một entity
|
|
84
|
+
|
|
85
|
+
1. Thêm model vào `prisma/schema/domain.prisma` → viết migration → `pnpm prisma:deploy`.
|
|
86
|
+
2. Tạo `src/configs/entities/<thing>.config.ts`, đăng ký ở `index.ts`, map khoá số
|
|
87
|
+
nhiều → model Prisma trong `src/lib/crud/index.ts`.
|
|
88
|
+
3. Khai resource trong `src/configs/permissions/<feature>.permissions.ts` →
|
|
89
|
+
`pnpm rbac-sync`.
|
|
90
|
+
4. Thêm mục menu trỏ `/crud/<key>`.
|
|
91
|
+
|
|
92
|
+
Xong. Không viết route, không viết engine.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Lấy thêm tính năng từ core
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
pnpm goerp-features list # các feature core có sẵn
|
|
100
|
+
pnpm goerp-features add <name> # chép schema + migration vào app
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Feature đã cắm sẵn trong template: `audit-logs`, `background-tasks`,
|
|
104
|
+
`error-logs`, `notifications`, `system-jobs`.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Lệnh hay dùng
|
|
109
|
+
|
|
110
|
+
| Lệnh | Việc |
|
|
111
|
+
| --- | --- |
|
|
112
|
+
| `pnpm dev` | Chạy dev (cổng 3010). |
|
|
113
|
+
| `pnpm type-check` | `tsc --noEmit`. |
|
|
114
|
+
| `pnpm test` | Ratchet kiến trúc. Chạy trước mỗi lần commit. |
|
|
115
|
+
| `pnpm rbac-sync` | Đồng bộ Permission Registry → DB (idempotent, chạy lại vô hại). |
|
|
116
|
+
| `pnpm prisma:deploy` | Áp migration đang chờ. **Cách duy nhất** đụng vào DB có dữ liệu thật. |
|
|
117
|
+
| `pnpm seed` | Vai trò + tài khoản admin + dữ liệu mẫu. Chạy TRƯỚC `rbac-sync`. |
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Triển khai
|
|
122
|
+
|
|
123
|
+
`Dockerfile` dựng image standalone (node:24-alpine, TZ Việt Nam). Di trú DB
|
|
124
|
+
**không** chạy trong container: chạy `pnpm prisma migrate deploy` từ CI trước khi
|
|
125
|
+
đổi sang bản mới, để migration hỏng thì dừng ngay ở đó thay vì làm container
|
|
126
|
+
khởi động lại vô hạn.
|
|
127
|
+
|
|
128
|
+
Cần `pnpm-lock.yaml` trong build context (`pnpm install` sinh ra ở lần cài đầu).
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Bẫy đã gặp
|
|
133
|
+
|
|
134
|
+
- Sau khi đổi schema → **restart `next dev`**. Đừng `rm -rf .next` khi dev đang chạy.
|
|
135
|
+
- Mục menu trỏ tới resource chưa khai trong registry sẽ **ẩn vĩnh viễn với mọi
|
|
136
|
+
người, kể cả admin**, không có lỗi nào hiện ra. `pnpm test` bắt trường hợp này.
|
|
137
|
+
- Biểu thức cron của core thực chất là `setInterval` tính TỪ LÚC BOOT — `0 1 * * *`
|
|
138
|
+
nghĩa là "mỗi 24 giờ kể từ khi khởi động", không phải "1 giờ sáng". Muốn đúng
|
|
139
|
+
giờ thì hẹn theo giờ rồi chặn bằng `isLocalHour()` (xem `src/instrumentation.ts`).
|
|
140
|
+
- Viết thêm đường ghi cấu hình thì phải `revalidateTag("system-settings", "max")`,
|
|
141
|
+
nếu không giao diện đọc giá trị cũ từ cache.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import fs from "fs"
|
|
2
|
+
import path from "path"
|
|
3
|
+
import { fileURLToPath } from "url"
|
|
4
|
+
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Khi lập trình core song song với app (`pnpm core:link`) hoặc khi app nằm
|
|
9
|
+
* trong một pnpm workspace, node_modules/@goerp/core là symlink trỏ RA NGOÀI
|
|
10
|
+
* thư mục app và turbopack báo "Symlink points out of the filesystem root".
|
|
11
|
+
*
|
|
12
|
+
* Nới root lên thư mục cha ĐẦU TIÊN chứa cả app lẫn core thật — đi ngược lên
|
|
13
|
+
* từng cấp chứ đừng đoán cứng ".." : store pnpm của workspace có thể nằm cách
|
|
14
|
+
* app 2–3 cấp, và chọn nhầm cấp thì Next không thấy được cả gói `next`.
|
|
15
|
+
*
|
|
16
|
+
* App độc lập (core cài từ npm, realpath nằm trong node_modules/.pnpm của
|
|
17
|
+
* chính app) giữ nguyên __dirname để `output: standalone` emit server.js đúng chỗ.
|
|
18
|
+
*/
|
|
19
|
+
const workspaceRoot = (() => {
|
|
20
|
+
try {
|
|
21
|
+
const real = fs.realpathSync(path.join(__dirname, "node_modules/@goerp/core"))
|
|
22
|
+
if (real.startsWith(__dirname + path.sep)) return __dirname
|
|
23
|
+
let dir = path.dirname(__dirname)
|
|
24
|
+
while (dir !== path.dirname(dir)) {
|
|
25
|
+
if (real.startsWith(dir + path.sep)) return dir
|
|
26
|
+
dir = path.dirname(dir)
|
|
27
|
+
}
|
|
28
|
+
} catch {}
|
|
29
|
+
return __dirname
|
|
30
|
+
})()
|
|
31
|
+
|
|
32
|
+
/** @type {import('next').NextConfig} */
|
|
33
|
+
const nextConfig = {
|
|
34
|
+
// Core ship .tsx thô nên app phải transpile. Cần CẢ HAI tên: đường import là
|
|
35
|
+
// "@goerp/core" (giữ qua alias pnpm) còn package thật trên đĩa là "@goplusvn/core".
|
|
36
|
+
transpilePackages: ["@goerp/core", "@goplusvn/core"],
|
|
37
|
+
|
|
38
|
+
// Docker image gọn: chỉ .next/standalone + static. Xem Dockerfile.
|
|
39
|
+
output: "standalone",
|
|
40
|
+
turbopack: { root: workspaceRoot },
|
|
41
|
+
// Next đòi outputFileTracingRoot trùng turbopack.root — nới cùng nhau.
|
|
42
|
+
outputFileTracingRoot: workspaceRoot,
|
|
43
|
+
|
|
44
|
+
// Không khai redirects() cho "/:lang": "/vi" CHÍNH LÀ trang chủ
|
|
45
|
+
// (src/app/[lang]/(main)/page.tsx). Nếu app tách riêng "/vi/home" thì mới
|
|
46
|
+
// thêm redirect, và nhớ rằng redirects() được nướng lúc BUILD — giá trị phải
|
|
47
|
+
// truyền bằng build arg, không phải env lúc chạy.
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default nextConfig
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@goerp/starter-app",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "next dev --turbopack --port 3010",
|
|
8
|
+
"build": "prisma generate && next build",
|
|
9
|
+
"postinstall": "prisma generate",
|
|
10
|
+
"start": "next start --port 3010",
|
|
11
|
+
"type-check": "tsc --noEmit",
|
|
12
|
+
"test": "vitest run",
|
|
13
|
+
"prisma:generate": "prisma generate",
|
|
14
|
+
"prisma:deploy": "prisma migrate deploy",
|
|
15
|
+
"prisma:studio": "prisma studio",
|
|
16
|
+
"seed": "tsx prisma/seed.ts",
|
|
17
|
+
"rbac-sync": "tsx scripts/rbac-sync.ts",
|
|
18
|
+
"goerp-features": "goerp-features"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@goerp/core": "npm:@goplusvn/core@^0.1.59",
|
|
22
|
+
"@prisma/adapter-pg": "^7.0.0",
|
|
23
|
+
"@prisma/client": "^7.0.0",
|
|
24
|
+
"bcryptjs": "^3.0.3",
|
|
25
|
+
"better-auth": "1.6.23",
|
|
26
|
+
"lucide-react": "0.446.0",
|
|
27
|
+
"next": "16.0.10",
|
|
28
|
+
"next-themes": "^0.2.1",
|
|
29
|
+
"pg": "^8.16.3",
|
|
30
|
+
"react": "19.2.0",
|
|
31
|
+
"react-dom": "19.2.0",
|
|
32
|
+
"server-only": "^0.0.1",
|
|
33
|
+
"sonner": "2.0.2",
|
|
34
|
+
"swr": "^2.3.6",
|
|
35
|
+
"zod": "3.23.8"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@tailwindcss/postcss": "4.0.17",
|
|
39
|
+
"@vitejs/plugin-react": "^5.0.4",
|
|
40
|
+
"@testing-library/react": "^16.3.0",
|
|
41
|
+
"@types/bcryptjs": "^2.4.6",
|
|
42
|
+
"@types/node": "22.9.0",
|
|
43
|
+
"@types/pg": "^8.16.0",
|
|
44
|
+
"@types/react": "19.0.12",
|
|
45
|
+
"@types/react-dom": "19.0.4",
|
|
46
|
+
"dotenv": "^16.4.7",
|
|
47
|
+
"jsdom": "^27.4.0",
|
|
48
|
+
"prisma": "^7.0.0",
|
|
49
|
+
"tailwindcss": "4.1.3",
|
|
50
|
+
"tsx": "^4.7.1",
|
|
51
|
+
"tw-animate-css": "1.2.5",
|
|
52
|
+
"typescript": "5.8.3",
|
|
53
|
+
"vitest": "^4.0.16"
|
|
54
|
+
}
|
|
55
|
+
}
|