Skip to content

Commit 45461f6

Browse files
JihaoXinclaude
andcommitted
Fix project creation: uuid-slug ID, auto-generate title from idea
Problems: - Project ID was random words (Keen-Ridge) instead of uuid-slug - No title when user only provides idea - Dashboard showed random slug as project name Fixes: - Project ID: uuid[:8]-slugified-title (e.g., a1b2c3d4-budget-aware-autonomous) - Auto-generate title from idea's first sentence if title not provided - name field uses the slug (human-readable) - Title syncs from LaTeX after writer generates paper (existing mechanism) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 749b559 commit 45461f6

File tree

1 file changed

+23
-16
lines changed

1 file changed

+23
-16
lines changed

ark/webapp/routes.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,14 @@ def _get_google_oauth() -> _OAuth | None:
8888

8989
# ── helpers ──────────────────────────────────────────────────────────────────
9090

91-
_SLUG_ADJECTIVES = ["Red", "Blue", "Swift", "Calm", "Bold", "Keen", "Warm", "Bright"]
92-
_SLUG_NOUNS = ["Comet", "Orbit", "Spark", "Quasar", "Nova", "Prism", "Pulse", "Ridge"]
93-
94-
def _random_slug() -> str:
95-
return f"{random.choice(_SLUG_ADJECTIVES)}-{random.choice(_SLUG_NOUNS)}"
91+
def _slugify(text: str, max_len: int = 48) -> str:
92+
"""Convert text to a URL-safe slug."""
93+
import re as _re
94+
slug = text.lower().strip()
95+
slug = _re.sub(r'[^a-z0-9\s-]', '', slug)
96+
slug = _re.sub(r'[\s_]+', '-', slug)
97+
slug = _re.sub(r'-+', '-', slug).strip('-')
98+
return slug[:max_len] if slug else "project"
9699

97100

98101
def _extract_and_validate_template(zip_bytes: bytes, paper_dir: Path) -> str | None:
@@ -526,7 +529,10 @@ def _try_submit_or_pending(project, pdir, session, settings) -> str:
526529

527530
@router.get("/", response_class=HTMLResponse)
528531
async def index():
529-
return HTMLResponse((_STATIC_DIR / "app.html").read_text())
532+
return HTMLResponse(
533+
(_STATIC_DIR / "app.html").read_text(),
534+
headers={"Cache-Control": "no-cache, no-store, must-revalidate"},
535+
)
530536

531537

532538
# ── auth ──────────────────────────────────────────────────────────────────────
@@ -766,14 +772,15 @@ async def api_create_project(
766772
if active:
767773
raise HTTPException(400, "You already have an active project. Wait for it to finish.")
768774

769-
project_id = _random_slug()
770-
# Ensure uniqueness — append -2, -3, … if the ID already exists
771-
with get_session(settings.db_path) as _s:
772-
base_id = project_id
773-
counter = 2
774-
while _s.get(Project, project_id):
775-
project_id = f"{base_id}-{counter}"
776-
counter += 1
775+
# Generate project ID: uuid prefix + slug from title/idea
776+
slug = _slugify(title or idea[:60] or "project")
777+
project_id = str(uuid.uuid4())[:8] + "-" + slug
778+
779+
# Auto-generate title from idea if not provided
780+
if not title and idea:
781+
# Use first sentence or first 100 chars of idea as initial title
782+
first_sentence = idea.split('.')[0].strip()
783+
title = first_sentence[:100] if first_sentence else idea[:100]
777784

778785
pdir = _project_dir(settings, user.id, project_id)
779786
pdir.mkdir(parents=True, exist_ok=True)
@@ -845,8 +852,8 @@ async def api_create_project(
845852
session,
846853
id=project_id,
847854
user_id=user.id,
848-
name=project_id,
849-
title=title or project_id,
855+
name=slug,
856+
title=title or slug,
850857
idea=idea,
851858
venue=venue,
852859
venue_format=venue_format,

0 commit comments

Comments
 (0)