diff --git a/app/api/memos.py b/app/api/memos.py index 94907b0..c70e165 100644 --- a/app/api/memos.py +++ b/app/api/memos.py @@ -173,6 +173,7 @@ async def list_memos( page_size: int = Query(20, ge=1, le=100), tag: str | None = Query(None, description="user_tags 또는 ai_tags 필터"), archived: bool = Query(False, description="true면 아카이브 목록"), + pinned: bool | None = Query(None, description="true면 핀 고정된 메모만"), ): """메모 목록 — 활성: 핀 우선 + 최신순 / 아카이브: 최신순 (핀 무시)""" base = select(Document).where( @@ -182,6 +183,9 @@ async def list_memos( Document.archived == archived, ) + if pinned is not None: + base = base.where(Document.pinned == pinned) + if tag: base = base.where( Document.user_tags.op("@>")(f'["{tag}"]') diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index 7e4ce36..e368ec4 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -1,51 +1,43 @@
-
-

대시보드

+
+ + +
+

대시보드

+ {#if systemView} + + {systemView.label} + + + {/if} +
{#if loading} - -
+ +
{#each Array(4) as _} -
- - - - - -
+ {/each} -
- - - - -
-
- - - - -
-
- - - - -
-
- - - - -
+ + {:else if summary} -
- - -
- - -

문서함

-

{(summary.documents_count ?? 0).toLocaleString()}

-

- {summary.today_added > 0 ? `+${summary.today_added} 오늘` : '-'} -

-
-
- - -

메모

-

{(summary.memos_count ?? 0).toLocaleString()}

-

-

-
-
- - - -

뉴스

-

{(summary.news_count ?? 0).toLocaleString()}

-

-

-
-
- - - -

승인 대기

-

{summary.inbox_count}

-

- {summary.inbox_count > 0 ? '분류하기 →' : '-'} -

-
-
- -
- -

법령 알림

-

{summary.law_alerts}

-

- {summary.law_alerts > 0 ? '오늘 변경' : '-'} -

-
-
- -
- -

시스템

- {#if systemView} -

{systemView.label}

-

{systemView.sub}

- {/if} -
-
+ + {#if pinnedMemos.length > 0} +
+ {#each pinnedMemos as memo (memo.id)} + + + {memo.content?.split('\n')[0] || '메모'} + + {/each} + {#if pinnedMemos.length >= 3} + 더보기 → + {/if}
+ {/if} - - + + + +
+

최근 활동

+
+ {#if summary.law_alerts > 0} + + 법령 {summary.law_alerts} + + {/if} +
+
+ + {#if summary.recent_documents.length > 0} + + {:else} + + {/if} +
+ + +
{ if (!e.currentTarget.open) pipelineManualClosed = true; }} + > + + + + 파이프라인 + + + {#if totalFailed > 0} + 실패 {totalFailed} + {/if} + {#if totalPending > 0} + 대기 {totalPending} + {/if} + {#if totalFailed === 0 && totalPending === 0} + 처리 완료 + {/if} + + + +
+ {#if pipelineRows.length > 0} +
+ {#each pipelineRows as row (row.stage)} +
+
+ {row.label} + + 대기 {row.pending} · + 처리 {row.processing} · + 실패 0 ? 'text-error' : ''}>{row.failed} + +
+
+ {#if row.pending > 0} +
+ {/if} + {#if row.processing > 0} +
+ {/if} + {#if row.failed > 0} +
+ {/if} +
+
+ {/each} +
+ {:else} +

최근 24시간 처리 작업 없음

+ {/if} +
+
+ {/if}
+ +