Phase 9: version message (FR-13)
- ใส่คำอธิบายแบบ commit message ได้ทุก flow ที่สร้าง version (Save & Version / Start Versioning / generate จากเว็บ) + แสดงใน version history ทุกหน้า - backend: DocumentVersion.Message (varchar 2048) + migration AddVersionMessage + BadRequest ตรวจความยาวก่อนแตะ MinIO (กัน 500 + orphan object) - add-in: ConfirmVersionDialog เพิ่ม textarea (Start Versioning ใช้ dialog ด้วย) + แสดง message ใน VersionHistoryPanel - web: ฟอร์มสร้างเอกสาร + หน้า detail แสดง message (desktop truncate + tooltip, mobile เต็มบรรทัด) - sync เอกสารทั้งหมด: spec v5 (FR-13/AC-16) + plan Phase 9 + acceptance-review 1–16 + README + CLAUDE.md + web/README - tests: backend 52 / addin 50 / web 36 — เขียวทั้งชุด Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
b47667f918
commit
7b20f12ede
28 changed files with 928 additions and 141 deletions
|
|
@ -1,75 +1,44 @@
|
|||
# Nuxt Minimal Starter
|
||||
# Web Portal — e-Court Documents Versioning
|
||||
|
||||
Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
|
||||
หน้าเว็บสำหรับจัดการ template + สร้างเอกสารจาก template (ได้ .docx ที่เป็น version 1 อัตโนมัติ) + ดูรายการเอกสาร/detail + re-generate — เป็นส่วนหนึ่งของ monorepo หลัก (ดู [../README.md](../README.md) สำหรับภาพรวมทั้งระบบ)
|
||||
|
||||
## Setup
|
||||
|
||||
Make sure to install dependencies:
|
||||
## สั่งรัน
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm install
|
||||
|
||||
# pnpm
|
||||
pnpm install
|
||||
|
||||
# yarn
|
||||
yarn install
|
||||
|
||||
# bun
|
||||
bun install
|
||||
npm run dev # http://localhost:5173 (ห้ามใช้ 3000 — ชนกับ add-in dev server)
|
||||
npm test # Vitest — 36 ตัว
|
||||
npm run build # production build (.output/)
|
||||
```
|
||||
|
||||
## Development Server
|
||||
ต้องรัน infra + backend ก่อน (docker compose + `dotnet run` ที่ backend) — login ผ่าน Keycloak ด้วย test user `testuser` / `Test1234!`
|
||||
|
||||
Start the development server on `http://localhost:3000`:
|
||||
## โครงสร้าง
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run dev
|
||||
|
||||
# pnpm
|
||||
pnpm dev
|
||||
|
||||
# yarn
|
||||
yarn dev
|
||||
|
||||
# bun
|
||||
bun run dev
|
||||
```
|
||||
app/
|
||||
app.vue # shell: sticky header + navbar + skip link
|
||||
assets/css/tailwind.css # design tokens (CSS variables) + @layer components (.btn/.input/.card/…)
|
||||
composables/ # useAuth (PKCE), useApi (Bearer + refresh), useTheme (light/dark)
|
||||
pages/ # ทุกหน้า: หน้าหลัก / templates (list/new/edit/documents) / documents (create/detail) / auth/callback
|
||||
types/api.ts # DTO mirror ของ backend
|
||||
utils/ # oidc, fieldValidation, snapshot — pure functions ไว้ unit test
|
||||
test/ # Vitest (happy-dom) — fieldValidation / useTheme / snapshot
|
||||
tailwind.config.ts # สี/fontSize/radius/shadow expose จาก CSS variables (rgb(var(--c-x) / <alpha-value>))
|
||||
```
|
||||
|
||||
## Production
|
||||
## Design system + responsive
|
||||
|
||||
Build the application for production:
|
||||
- **สี/ฟอนต์/radius/shadow เป็น token ทั้งหมด** — CSS variables (`:root` + `.dark`) ใน `app/assets/css/tailwind.css`, derive จาก scheme ของ admincourt.go.th (primary `#0000EE`, elevated ครีม `#FBF7EC`, ฟอนต์ Sukhumvit Set → Sarabun ผ่าน Google Fonts) · dark mode พลิกที่ตัวแปร ไม่ใช้ `dark:` utility คู่
|
||||
- **Component classes กลาง** — `.btn*` / `.input` / `.label` / `.card` / `.table-card` / `.badge*` / `.alert*` / `.spinner` ใน `@layer components`
|
||||
- **Responsive ทุกหน้า** — ตารางทุกตัว dual-render (desktop ตาราง / ต่ำกว่า `md` เป็น card list), page header stack บนมือถือ, ฟอร์ม action row `flex-col-reverse → sm:flex-row`
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run build
|
||||
⚠️ **กติกาสำคัญ:**
|
||||
- แก้ `tailwind.config.ts` แล้วต้อง **restart dev server** ทุกครั้ง
|
||||
- CSS variables ต้องเป็น **RGB triplet เว้นวรรค** (`0 0 238`) — ใส่ hex จะ break `/opacity` utilities เงียบๆ
|
||||
- ต้องระบุ `tailwindcss.cssPath: '~/assets/css/tailwind.css'` ใน `nuxt.config.ts` (default resolve ผิดบน Nuxt 4 → fallback ไปไฟล์ default ของ tailwindcss package แบบเงียบ — ดูกติกา #14 ของ CLAUDE.md หลัก)
|
||||
- Token เก็บใน memory เท่านั้น — persist ได้เฉพาะ theme (localStorage) + refresh token/PKCE verifier (sessionStorage อายุสั้น)
|
||||
|
||||
# pnpm
|
||||
pnpm build
|
||||
## Config
|
||||
|
||||
# yarn
|
||||
yarn build
|
||||
|
||||
# bun
|
||||
bun run build
|
||||
```
|
||||
|
||||
Locally preview production build:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run preview
|
||||
|
||||
# pnpm
|
||||
pnpm preview
|
||||
|
||||
# yarn
|
||||
yarn preview
|
||||
|
||||
# bun
|
||||
bun run preview
|
||||
```
|
||||
|
||||
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
|
||||
ค่า default ชี้ dev ในพื้นที่ override ผ่าน env ได้ทั้งหมด (ดู [.env.example](.env.example)): `NUXT_PUBLIC_API_BASE_URL`, `NUXT_PUBLIC_KEYCLOAK_AUTHORITY`, `NUXT_PUBLIC_KEYCLOAK_CLIENT_ID`
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ onMounted(load)
|
|||
<p class="font-medium">v{{ v.versionNumber }}</p>
|
||||
<p class="mt-1 text-xs text-muted">{{ formatDateTime(v.createdAt) }}</p>
|
||||
<p class="mt-0.5 font-mono text-xs text-muted">{{ v.createdByUserId.slice(0, 8) }}…</p>
|
||||
<p v-if="v.message" class="mt-1 text-sm break-words">{{ v.message }}</p>
|
||||
</div>
|
||||
<div class="flex shrink-0 flex-col items-end gap-2">
|
||||
<button
|
||||
|
|
@ -241,7 +242,16 @@ onMounted(load)
|
|||
class="cursor-pointer hover:bg-surface-muted/60"
|
||||
@click="expandedVersionId = expandedVersionId === v.versionId ? null : v.versionId"
|
||||
>
|
||||
<td class="px-4 py-3 font-medium">v{{ v.versionNumber }}</td>
|
||||
<td class="px-4 py-3 font-medium">
|
||||
v{{ v.versionNumber }}
|
||||
<p
|
||||
v-if="v.message"
|
||||
class="max-w-md truncate text-xs font-normal text-muted"
|
||||
:title="v.message"
|
||||
>
|
||||
{{ v.message }}
|
||||
</p>
|
||||
</td>
|
||||
<td class="px-4 py-3">{{ formatDateTime(v.createdAt) }}</td>
|
||||
<td class="px-4 py-3 font-mono text-xs text-muted">{{ v.createdByUserId.slice(0, 8) }}…</td>
|
||||
<td class="px-4 py-3 text-right whitespace-nowrap">
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ const templateId = computed(() => String(route.params.templateId))
|
|||
const detail = ref<TemplateDetail | null>(null)
|
||||
const values = ref<Record<string, string>>({})
|
||||
const issues = ref<Record<string, string>>({})
|
||||
/** คำอธิบาย version แบบ commit message (FR-13) — ทางเลือก · re-generate ไม่ prefill เพราะเป็นเอกสารใหม่ */
|
||||
const message = ref('')
|
||||
|
||||
/** เอกสารต้นทางของ re-generate (จาก ?from=) — ใช้ทั้ง prefill และ banner บอกบริบท */
|
||||
const fromDoc = ref<{ id: string; fileName: string } | null>(null)
|
||||
|
|
@ -82,7 +84,7 @@ async function submit() {
|
|||
result.value = await apiJson<GenerateDocumentResponse>('/api/documents/generate', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ templateId: templateId.value, values: values.value }),
|
||||
body: JSON.stringify({ templateId: templateId.value, values: values.value, message: message.value.trim() || null }),
|
||||
})
|
||||
window.scrollTo({ top: 0 })
|
||||
} catch (err) {
|
||||
|
|
@ -113,6 +115,7 @@ function resetForm() {
|
|||
downloadError.value = null
|
||||
issues.value = {}
|
||||
values.value = { ...blankValues(), ...prefill.value }
|
||||
message.value = ''
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
|
|
@ -220,6 +223,18 @@ onMounted(load)
|
|||
<p v-if="issues[f.key]" class="mt-1 text-xs text-error-strong">{{ issues[f.key] }}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="doc-message" class="label">คำอธิบาย version (ไม่บังคับ)</label>
|
||||
<textarea
|
||||
id="doc-message"
|
||||
v-model="message"
|
||||
class="input"
|
||||
rows="2"
|
||||
maxlength="2048"
|
||||
placeholder="เช่น ฉบับเสนอลงนามครั้งแรก"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="sortedFields.length === 0" class="empty-state">
|
||||
template นี้ไม่มี field definitions —
|
||||
<NuxtLink :to="`/templates/${detail.id}/edit`" class="link">ตรวจสอบที่หน้าจัดการ template</NuxtLink>
|
||||
|
|
|
|||
|
|
@ -98,4 +98,6 @@ export interface VersionListItem {
|
|||
createdByUserId: string
|
||||
contentHash: string
|
||||
fields: unknown
|
||||
/** คำอธิบาย version แบบ commit message ที่ผู้ใช้พิมพ์ตอนสร้าง (FR-13) — null ได้ */
|
||||
message: string | null
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue