Skip to content

Fix core-feature bugs and broken flows found in review - #2

Merged
kwakhyun merged 14 commits into
mainfrom
claude/project-thread-zmx0ab
Oct 1, 2026
Merged

kwakhyun merged 14 commits into
mainfrom
claude/project-thread-zmx0ab

Conversation

@kwakhyun

Copy link
Copy Markdown
Owner

Requested by 토리나나 · project thread

Before: a review of the core features turned up these problems:

  • A backup file could put problems into every user's library, including the home recommendation.
  • Restoring on PostgreSQL silently dropped each project's workshop, practice and code dialogues.
  • A single failed project review or code dialogue locked that question with a permanent 409.
  • A failed background analysis only ever said "분석을 완료하지 못했습니다".
  • A revision showed up as a duplicate project class.
  • Several flows lost work or restarted from step 1, and failed AI calls still used up allowances.

After: imported problems stay private to the importer, and restores keep every project job. Failed reviews and dialogues can be retried with edited answers, and analysis failures show their real reason. Revisions live inside their root project, and interrupted work resumes where it left off. Failed AI calls refund the personal allowance.

Changes by area

Coding training, drafts, backup, limits

  • Restored problems stay private to the importer, are forced to non-curated, and have their createdAt clamped.
  • PostgreSQL restores every project job, matching SQLite.
  • Import validates before charging, maps only real mismatches to 400, and the global import pools are widened.
  • Review and coach refund the personal allowance when the AI call fails. The workspace shows "오늘 N회 남음".
  • Without a trusted client IP (non-Vercel hosts), the network-keyed guest limits are skipped.
  • A closed tab's unsaved draft is offered with 불러오기 / 버리기, and archived drafts can be deleted.
  • A lost save acknowledgement no longer reports a conflict with your own code.
  • Review code is stored exactly as submitted.
  • Missing problems get a not-found state. Bookmarks update in place without blanking the table. Menu links reset the filters.
  • The guest cookie is minted in src/proxy.ts, so parallel first requests share one owner. This fixes the "로그인 계정이 변경되었습니다" error on a fresh deep link.

Project check / 내 프로젝트

  • A failed review or dialogue attempt releases its request id.
  • Analysis failures persist a public reason, which /status returns and the UI shows.
  • Revisions attach to their root through revisionOf. They are hidden from the class list and versions, reuse the root's practice and workshop, and are capped at 3 per root.
  • Focus refreshes happen in the background without hiding the page. The last good detail is kept when a refetch fails.
  • Pending analyses resume on the form, and duplicate runs are blocked.
  • One shared deletion cleanup helper serves both pages.
  • The new-project draft is kept when a revision starts.

AI workshop, missions, code-understanding lab

  • Service missions show choices and fixes in a deterministic per-mission order. Saved answers keep their grading.
  • Labs reopen at the first step still missing evidence.
  • The workshop hero hands the URL over and starts the analysis. Topic answers and notes autosave locally.
  • Bad ?check= ids offer a way out.
  • "다음 수업" keeps the project context, and completed lessons reopen on the summary.
  • A visible notice appears when the 80-action limit is reached.
  • The sandbox forwards worker errors, explains sync timeouts, and shows non-Error throws. It times only learner execution.
  • Retry variants get their own situation text and a variant-specific check that their starting code misses.

Start guide, security check

  • The guide has its own global budget and refunds failed AI calls. The prompt now states the real generation limits.
  • The security check reads headers for any status or content type and allows query strings on redirects. It accepts quoted HSTS max-age.
  • The CORS challenge persists per origin. The page reads its scope from the light /api/guide endpoint, and failed fetches refund the personal limit.

How

Every area was changed with its own unit tests, including SQLite contract tests for the store changes.

Local checks all pass: format:check, lint, typecheck, knip, and vitest (516 passed, 38 PostgreSQL tests skipped without TEST_DATABASE_URL).

I also clicked through the main pages in Chromium against a local dev server:

  • A fresh deep link to /problems/fe-search-race worked 4 of 4 times.
  • /problems/nonexistent shows the not-found state.
  • Bookmarking shows no skeleton and keeps focus.
  • /learn/ai/project?check=missing offers a way out.
  • The variant lab shows its situation text.

E2E suites were not run. The PostgreSQL-specific SQL is written to mirror SQLite but was not executed against a real PostgreSQL.

🤖 Generated with Claude Code

https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR


Generated by Claude Code

…rvation limit

Service-case missions now render prediction/transfer choices and fixes in a
deterministic per-mission order; stored indices still point at the source
arrays so saved progress keeps its grading. Code-understanding labs reopen on
the first step still missing evidence, and the mission practice panel shows a
visible notice when the 80-action observation limit is reached.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR
- Record the importing owner on problems first created by a backup and
  hide them from other owners' library, stats, recommendation and links;
  force their source to ai and clamp future createdAt.
- Insert every restored project job on PostgreSQL like SQLite.
- Validate backup references before spending import allowance, map only
  backup mismatches to 400 and widen the global import pools.
- Refund the personal review/coach allowance when the AI call fails.
- Skip network-keyed AI/import limits when no trusted client IP exists.
- Store review code exactly as submitted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR
The guide spent the core ai:global windows, so guide traffic could exhaust
review, generation and analysis. It now uses guide:global:hour/day. When
the provider call fails and the basic guide is shown, the personal daily
windows are refunded via a new StoreQueries.refundLimits; burst, network
and service windows still count the attempt. The guide prompt now states
the real generation allowance from ai-access (guest 2, member 6 per day)
and its version is bumped.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR
- Redirect targets chosen by the site may carry query strings on the
  security path; user input and SSRF checks stay strict, and a rejected
  redirect no longer reports an input-validation message.
- readPublicDocument gains an anyResponse option so headers are inspected
  for any status and content type (bot challenges, 404, JSON). Project
  checks keep the 200 + HTML contract.
- Reports show the redirect route and non-200 final status, without
  site-chosen query strings.
- Accept the RFC 6797 quoted HSTS max-age form.
- Target-site failures (422) refund only the per-session window.
- Persist the CORS ownership challenge per scope and origin in
  sessionStorage and key the audit panel by origin.
- Read the session scope from GET /api/guide instead of /api/workspace.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR
Forward worker-side errors instead of a generic result failure, describe
QuickJS interrupts as a synchronous loop timeout, show values thrown or
rejected without an Error, and start the 12s execution timer only after the
engine is ready (engine loading has its own 30s limit).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR
- Release a failed or expired review/code-dialogue job before re-leasing
  its fixed ID, so edited answers no longer hit a permanent 409.
- Store a user-safe reason (HttpError message and status) on a failed
  background analysis and return it from the status endpoint.
- Link revisions to their root analysis: hide them from class lists and
  version history, list them on the root detail, resolve practice,
  workshop and training lookups to the root, cap total revisions per
  root, and remove revisions with their root.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR
- Refresh /project-check in the background on focus without hiding the
  workspace, re-reading loaded history pages; keep the last good detail
  when a refetch fails and clear a selection that no longer exists.
- Show pending background analyses in the form with progress and cancel,
  block a second analysis meanwhile and open the result when it ends.
- Show the stored failure reason when background analysis fails.
- Open revisions without adding them to the history list or clearing
  the new-project draft, and link revisions from the root views.
- Use one client cleanup helper after deleting a project on either page.
- Show the review credit cost on the code dialogue button.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR
- The hero repository form states the cost and hands the URL to the
  workshop, which starts the analysis on arrival and continues into the
  learning generation once, per tab, without another click.
- Unsaved topic answers and notes are kept per check and topic in
  localStorage and cleared after a successful save.
- A missing or malformed check id offers a way to pick another project.
- "Next lesson" keeps the project/topic query; completed lessons reopen on
  their summary.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR

# Conflicts:
#	src/lib/server/postgres-store.ts
…t cookie up front

- Offer a closed tab's unsaved draft with load/discard, let archived drafts be
  deleted and drop a recovered draft once newer code is saved.
- Continue from our own earlier write when a save acknowledgement was lost
  instead of reporting a conflict.
- Show a not-found state for missing problems and today's remaining reviews
  next to the review action.
- Update bookmarks in place without blanking the table, and let menu links
  reset the library filters to the URL.
- Mint the guest cookie in the proxy for page loads so parallel first API
  calls share one owner.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR
Each "다시 도전" variant now explains its own service situation (address
autocomplete, booking headcount, activity log, worker config, notification
job, billing history) and adds a check set in that situation which its
starting code misses. The variant suite has its own lab version so earlier
runs are not reused against the new checks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sRbFpcfxw1wtGd6WNgngR
@kwakhyun kwakhyun self-assigned this Sep 30, 2026
@vercel

vercel Bot commented Sep 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
codefit Ready Ready Preview Sep 30, 2026 10:15pm UTC

@kwakhyun
kwakhyun merged commit f3383fb into main Oct 1, 2026
3 checks passed
@kwakhyun
kwakhyun deleted the claude/project-thread-zmx0ab branch October 1, 2026 07:00

This branch was successfully deployed

1 active deployment
Preview — 756ef360 Deployed Sep 30, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants