Assistant-scoped chat URLs (feature 133)
Assistant-scoped chat URLs (feature 133)
Section titled “Assistant-scoped chat URLs (feature 133)”Summary: Ajutant now supports URL-safe assistant slugs that produce shareable, bookmark-friendly chat links scoped to a specific assistant.
Status
Section titled “Status”- Feature id: 133
- Name: assistant-scoped-chat-urls
- Status: partial
What this feature changes
Section titled “What this feature changes”This feature addresses two problems with the previous chat URL approach:
- Navigation mismatch: when you are in an active conversation at
/chat?id=..., the Assistants tab can light up because the existing matcher for Assistants owns all/chatURLs. After the routing changes, users expect Chats to stay highlighted. - Opaque chat URLs: URLs like
/chat?assistantId=<id>are not bookmark-friendly or share-friendly.
The cleaner fix is to move chat URLs to proper paths that are:
- Assistant-scoped
- Slug-readable
- Shareable
- REST-shaped (path-based, not query-string-driven)
URL structure (assistant-scoped)
Section titled “URL structure (assistant-scoped)”Ajutant uses separate URL trees for specialists and chatbots, even though they are architecturally similar objects.
Chatbot chat URLs
Section titled “Chatbot chat URLs”- Base:
/chats/<chatbot-slug> - With conversation id:
/chats/<chatbot-slug>/<convId>
Specialist chat URLs
Section titled “Specialist chat URLs”- Base:
/assistants/<slug>/chats - With conversation id:
/assistants/<slug>/chats/<convId>
When there is no conversation id in the URL
Section titled “When there is no conversation id in the URL”For both trees, when the URL does not include a conversation id, the server renders an empty-state landing screen with the message input.
- Sending a message creates a conversation.
- The URL transitions to the kind-appropriate
[/<convId>]form.
Slug behavior and redirects
Section titled “Slug behavior and redirects”Slug is decorative, routing keys off conversation id
Section titled “Slug is decorative, routing keys off conversation id”- Routing keys off the conversation id (or the assistant id when there is no convId yet).
- The slug is decorative.
Slug is cosmetic-only, with canonical redirects
Section titled “Slug is cosmetic-only, with canonical redirects”- The slug is regenerated on rename so URLs reflect the current name.
- If a URL’s slug does not match the current canonical slug (for example, the assistant was renamed, or a bookmark is stale), the system issues a single 308 redirect to the canonical URL.
Foundation work: slug column backfill (migration dependency)
Section titled “Foundation work: slug column backfill (migration dependency)”Before end users see the new URL routes, the platform must have a URL-safe slug available for each assistant.
What the migration does
Section titled “What the migration does”- Every existing assistant gets a URL-safe
slugderived from its name. - Slug format: lowercase, kebab-case, ASCII-safe.
- Slug uniqueness is enforced.
- Collisions resolve by adding disambiguators like
-2,-3. - New assistants auto-generate a slug on insert.
Independent test (what to verify)
Section titled “Independent test (what to verify)”In a clean staging environment:
- After migration, every assistant row has a non-null, URL-safe, unique slug.
- Insert a new assistant via the existing admin path: its slug is auto-generated.
- Insert a second assistant with the same name: its slug gets a
-2disambiguator. - Existing URL behavior is unchanged at this point.
Acceptance scenarios (as specified)
Section titled “Acceptance scenarios (as specified)”- Given an existing tenant with 50+ assistants and the migration has been applied, When I query the
assistantstable, Then every row has a non-nullslugvalue of length ≥ 1 and matches the URL-safe pattern^[a-z0-9-]+$. - Given the migration has been applied, When I insert a new assistant, Then its slug is auto-generated.
- Given the migration has been applied, When I insert a second assistant with the same name, Then its slug includes a disambiguator (for example,
-2).
Examples
Section titled “Examples”Note: The exact
<chatbot-slug>and<convId>values depend on your tenant data.
- Chatbot landing (no conversation yet):
/chats/<chatbot-slug>
- Chatbot conversation:
/chats/<chatbot-slug>/<convId>
- Specialist conversation:
/assistants/<slug>/chats/<convId>
If you open a stale link with an old slug, you should expect a 308 redirect to the canonical path.
Notes for reviewers and implementers
Section titled “Notes for reviewers and implementers”- The spec describes retiring the query-string-driven catch-all
/chatapproach as part of the routing-layer refactor. - This document only covers what is stated in the feature catalogue entry and spec overview. If you need UI details (for example, where the Chats tab highlights), those are not fully specified here.