Add English level settings, improve content structuring and rendering

- Add english_level column to users table (CEFR with TOEIC mapping)
- Add UserController (GET/PATCH /api/users/me) and Settings page
- Enhance structuring prompts: sequential TOC, no summary sections,
  no content overlap, English expression extraction by CEFR level
- Remove sub-TOC analysis (caused content repetition), use simple
  per-section generation with truncation detection and continuation
- Fix CLOB truncation: explicit Clob-to-String conversion in repository
- Replace regex-based markdown rendering with react-markdown
- Add wallet renewal procedure to troubleshooting docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-12 23:48:38 +00:00
parent 4cde775809
commit f9f710ec90
12 changed files with 434 additions and 73 deletions

View File

@@ -5,6 +5,7 @@ import { useParams, useRouter } from "next/navigation";
import AuthGuard from "@/components/auth-guard";
import NavBar from "@/components/nav-bar";
import { useApi } from "@/lib/use-api";
import ReactMarkdown from "react-markdown";
interface Category {
ID: string;
@@ -306,19 +307,25 @@ export default function KnowledgeDetailPage() {
{showStructured ? "▼ 정리된 내용 숨기기" : "▶ 정리된 내용 보기"}
</button>
{showStructured && (
<div className="bg-[var(--color-bg-card)] rounded-xl p-6 border border-[var(--color-border)] prose prose-invert max-w-none">
<div
className="text-sm leading-relaxed whitespace-pre-wrap"
dangerouslySetInnerHTML={{
__html: item.STRUCTURED_CONTENT
.replace(/^### (.+)$/gm, '<h3 class="text-base font-bold mt-4 mb-2 text-[var(--color-text)]">$1</h3>')
.replace(/^## (.+)$/gm, '<h2 class="text-lg font-bold mt-5 mb-2 text-[var(--color-text)]">$1</h2>')
.replace(/^# (.+)$/gm, '<h1 class="text-xl font-bold mt-6 mb-3 text-[var(--color-text)]">$1</h1>')
.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
.replace(/^- (.+)$/gm, '<li class="ml-4 list-disc">$1</li>')
.replace(/^(\d+)\. (.+)$/gm, '<li class="ml-4 list-decimal">$2</li>')
}}
/>
<div className="bg-[var(--color-bg-card)] rounded-xl p-6 border border-[var(--color-border)] max-w-none">
<div className="structured-content text-sm leading-relaxed">
<ReactMarkdown
components={{
h1: ({children}) => <h1 className="text-xl font-bold mt-6 mb-3">{children}</h1>,
h2: ({children}) => <h2 className="text-lg font-bold mt-5 mb-2">{children}</h2>,
h3: ({children}) => <h3 className="text-base font-bold mt-4 mb-2">{children}</h3>,
p: ({children}) => <p className="mb-3">{children}</p>,
ul: ({children}) => <ul className="list-disc ml-5 mb-3 space-y-1">{children}</ul>,
ol: ({children}) => <ol className="list-decimal ml-5 mb-3 space-y-1">{children}</ol>,
li: ({children}) => <li className="leading-relaxed">{children}</li>,
strong: ({children}) => <strong className="font-bold">{children}</strong>,
blockquote: ({children}) => <blockquote className="border-l-2 border-[var(--color-primary)] pl-4 my-3 italic text-[var(--color-text-muted)]">{children}</blockquote>,
code: ({children}) => <code className="bg-[var(--color-bg-hover)] px-1.5 py-0.5 rounded text-xs">{children}</code>,
}}
>
{item.STRUCTURED_CONTENT}
</ReactMarkdown>
</div>
</div>
)}
</div>