diff --git a/README.ko.md b/README.ko.md
index 4aab301..7350765 100644
--- a/README.ko.md
+++ b/README.ko.md
@@ -11,7 +11,7 @@
셀프호스팅 가정용 재고·바코드 관리 — 기존 제품 바코드(UPC/EAN), 직접 발급한 QR 라벨, Matter 페어링 코드를 스캔해서 집안 물건을 관리합니다. 연속 스캔으로 입고·소비를 처리하고, 대시보드에서 재고부족·유통기한을 한눈에 보고, 라벨을 인쇄합니다.
-> 현재 릴리스: **v0.6.2**
+> 현재 릴리스: **v0.6.3**
문서: [`docs/ROADMAP.md`](./docs/ROADMAP.md)
@@ -20,10 +20,10 @@
## 기능
- 중첩 위치(방 / 선반 / 상자)를 들여쓰기 트리로 표시, 카테고리
-- 수량, 재고부족 기준 수량, 유통기한·보증 만료일, 가격, 사진, 메모 — 이름·단위는 아이템 상세에서 바로 인라인 편집. 직접 등록 폼에서 촬영 또는 갤러리 선택으로 바로 사진을 넣을 수 있고(업로드 시 자동 리사이즈), 가격은 매번 입력하는 대신 설정에서 한 번 고른 기본 통화(원/달러)를 그대로 씀
+- 수량, 재고부족 기준 수량, 유통기한·보증 만료일, 가격, 메모 — 이름·단위는 아이템 상세에서 바로 인라인 편집. 직접 등록 폼에서 촬영 또는 갤러리 선택으로 사진을 하나 골라둘 수 있고(업로드 시 자동 리사이즈), 가격은 매번 입력하는 대신 설정에서 한 번 고른 기본 통화(원/달러)를 그대로 씀
- 통합 `Item` + `Barcode` 모델 — 기존 UPC/EAN, 직접 발급 내부 QR(아이템 딥링크), Matter 페어링 코드, 수동 입력 시리얼번호(Matter 코드는 실제 커미셔닝이 아니라 식별자 용도임을 안내하는 문구 포함)를 하나의 바코드 타입으로
- 수량 관리와 별개로 자산(기기) 모드 — 아이템을 **자산**으로 전환하면 개별 기기 하나를 추적: 상태(신품/사용중/수리필요/폐기), 시리얼번호 바코드 등록, 정비 이력(날짜·내용·비용) 기록. 자산은 수량 스텝퍼·재고부족 필드가 숨겨지고 장보기/재고부족 로직에서 제외되며, 자산 바코드를 스캔하면 수량 조정 없이 해당 자산의 상세 페이지로 바로 이동합니다.
-- 영수증·설명서·보증서 등 파일 첨부 — 아이템이나 자산에 PDF/이미지 형식의 여러 문서를 직접 업로드하여 보관할 수 있고, 업로드 시 이미지는 자동 리사이즈됩니다.
+- 영수증·설명서·보증서·사진 등 파일 첨부 — 업로드 창구를 하나로 통합해 아이템·자산마다 PDF/이미지 문서를 여러 개 올려 보관하고, 파일 링크가 아니라 실제 썸네일로 미리 보여줍니다(업로드 시 이미지는 자동 리사이즈). 이미지 첨부 중 아무거나 대표 사진으로 지정할 수 있고, 이름 옆에 프로필 사진처럼 작게 표시됩니다 — 이미지가 하나뿐이면 자동으로 대표가 되고, 여러 장이면 직접 골라야 합니다.
- 연속 카메라 스캔: **입고(+1)** / **소비(−1)** 모드, 화면 전환 없이 계속 스캔 — 직접 등록 폼이나 바코드/Matter 코드 추가에서도 카메라 스캔 지원. 실사용 인식률/속도를 위해 포맷 제한·고해상도·연속 오토포커스로 튜닝했고, 스캔 성공 시 삑 소리·진동, 저조도용 플래시 토글 지원. 새로 자동 생성된 아이템은 그 자리에서 바로 위치·기준수량을 채우는 미니시트 제공
- 외부 제품 조회 연동을 다중 선택 가능(Open Food Facts, UPCItemDB, 네이버쇼핑) — 원하는 제공자만 켜거나 아예 꺼서 조회 자체를 생략
- 대시보드: 총 자산가치, 재고부족·유통기한 임박 항목을 전면에, 첫 사용 시 온보딩 체크리스트(위치·알림·공개URL) 제공
diff --git a/README.md b/README.md
index 2d50717..d870a44 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@
Self-hosted home inventory & barcode manager — track everything you own by scanning existing product barcodes (UPC/EAN), self-issued QR labels, or Matter pairing codes. Restock/consume with one continuous scan, watch low-stock and expiry from the dashboard, and print labels.
-> Current release: **v0.6.2**
+> Current release: **v0.6.3**
Docs: [`docs/ROADMAP.md`](./docs/ROADMAP.md)
@@ -20,10 +20,10 @@ Docs: [`docs/ROADMAP.md`](./docs/ROADMAP.md)
## Features
- Nested locations (rooms / shelves / boxes) rendered as an indented tree, and categories
-- Items with quantity, low-stock threshold, expiry & warranty dates, price, photo, notes — name and unit are inline-editable right on the item detail page. Photos can be taken *or* picked from the gallery right in the "add manually" form (auto-resized on upload), and price uses a default currency (KRW/USD, set once in Settings) instead of typing it on every item
+- Items with quantity, low-stock threshold, expiry & warranty dates, price, notes — name and unit are inline-editable right on the item detail page. An optional photo can be taken *or* picked from the gallery right in the "add manually" form (auto-resized on upload), and price uses a default currency (KRW/USD, set once in Settings) instead of typing it on every item
- Unified `Item` + `Barcode` model — existing UPC/EAN, self-issued internal QR (deep-links to the item), a Matter pairing code, or a manually-entered serial number (with inline copy explaining Matter codes are an identifier only, not real commissioning), all as one barcode type
- Asset mode alongside quantity tracking — flip an item to **Asset** to track a single physical device: condition (new / in use / needs repair / retired), a serial-number barcode entry, and a maintenance-history log (date, description, cost). Asset items hide the quantity stepper/low-stock fields, are excluded from shopping-list/low-stock logic, and scanning an asset's barcode redirects to its detail page instead of adjusting quantity
-- File attachments for receipts, manuals, and warranties — upload and store multiple PDF or image documents per item/asset, with image auto-resizing on upload
+- File attachments for receipts, manuals, warranties, and photos — a single upload flow stores multiple PDF or image documents per item/asset, shown as real thumbnails (not just file links), with image auto-resizing on upload. Any image attachment can be set as the item's representative photo — shown as a small profile-style avatar next to the item name, automatic when there's only one image and a manual picker once there are several
- Continuous camera scanning: **Restock (+1)** / **Consume (−1)** modes, no screen transition between scans; camera scan is also available when registering an item manually or adding a barcode/Matter code. Tuned for real-world speed/accuracy (format hints, higher resolution, continuous autofocus), with an audible beep, haptic buzz, and a low-light flash toggle. A newly auto-created item gets a quick inline sheet to set its location/threshold on the spot
- Pluggable external product lookup (Open Food Facts, UPCItemDB, Naver Shopping) — pick which providers to use per barcode scan, or turn lookup off entirely
- Dashboard: total inventory value, low-stock and expiring-soon items front and center, plus a first-run onboarding checklist (location, notifications, public URL)
diff --git a/apps/api/package.json b/apps/api/package.json
index 5b8b074..8cce174 100644
--- a/apps/api/package.json
+++ b/apps/api/package.json
@@ -1,6 +1,6 @@
{
"name": "@stash/api",
- "version": "0.6.2",
+ "version": "0.6.3",
"private": true,
"type": "module",
"scripts": {
diff --git a/apps/api/src/routes/items.ts b/apps/api/src/routes/items.ts
index 6377e1a..5225c88 100644
--- a/apps/api/src/routes/items.ts
+++ b/apps/api/src/routes/items.ts
@@ -408,7 +408,10 @@ export async function itemRoutes(app: FastifyInstance) {
const item = await prisma.item.update({
where: { id },
data,
- include: ITEM_INCLUDE,
+ // attachments도 함께 내려줘야 한다 — 그냥 ITEM_INCLUDE만 쓰면 이름/위치 등 아무
+ // 필드나 하나 수정할 때마다 응답에 attachments가 빠져서 화면에서 첨부파일 목록이
+ // 사라져 보이는 문제가 있었다(대표 사진 지정도 이 PATCH를 타므로 같은 증상 발생).
+ include: { ...ITEM_INCLUDE, attachments: true },
});
void fireInventoryWebhook("item.updated", item);
return item;
diff --git a/apps/web/app/categories/page.tsx b/apps/web/app/categories/page.tsx
index b9707e1..b193e1c 100644
--- a/apps/web/app/categories/page.tsx
+++ b/apps/web/app/categories/page.tsx
@@ -85,7 +85,7 @@ export default function CategoriesPage() {
{c.parentId && · {t("subOf", { name: parentName(c.parentId) ?? "" })}}
· {t("itemCount", { n: c._count?.items ?? 0 })}
-