fix(course): stop capping public course slug length
Public course slugs carry a -<timestamp> uniqueness suffix that pushes them past the 80-char ZSlug cap, so the org-site lookup returned a 400 and the page fell through to the landing page instead of redirecting to the first lesson. The course.slug column is unbounded, so validate the public-course route param with a no-max ZCourseSlug.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import * as z from 'zod';
|
||||
|
||||
import { ZSlug } from '../shared/slug';
|
||||
import { ZCourseSlug, ZSlug } from '../shared/slug';
|
||||
|
||||
/**
|
||||
* Route params + query schemas for the anonymous, SEO-indexable public course
|
||||
@@ -8,12 +8,12 @@ import { ZSlug } from '../shared/slug';
|
||||
*/
|
||||
|
||||
export const ZPublicCourseBySlugParam = z.object({
|
||||
courseSlug: ZSlug
|
||||
courseSlug: ZCourseSlug
|
||||
});
|
||||
export type TPublicCourseBySlugParam = z.infer<typeof ZPublicCourseBySlugParam>;
|
||||
|
||||
export const ZPublicCourseItemParam = z.object({
|
||||
courseSlug: ZSlug,
|
||||
courseSlug: ZCourseSlug,
|
||||
itemSlug: ZSlug
|
||||
});
|
||||
export type TPublicCourseItemParam = z.infer<typeof ZPublicCourseItemParam>;
|
||||
|
||||
@@ -15,6 +15,16 @@ export const ZSlug = z
|
||||
});
|
||||
export type TSlug = z.infer<typeof ZSlug>;
|
||||
|
||||
/**
|
||||
* Course slugs are `slugify(title)` (capped at 80) plus a `-<timestamp>` uniqueness
|
||||
* suffix, so they routinely exceed the 80-char `ZSlug` cap. The `course.slug` column is
|
||||
* unbounded `varchar` and there's no technical reason to cap the URL, so don't.
|
||||
*/
|
||||
export const ZCourseSlug = z.string().min(1, { message: 'Slug is required' }).regex(SLUG_REGEX, {
|
||||
message: 'Slug must be lowercase letters, numbers, and single dashes'
|
||||
});
|
||||
export type TCourseSlug = z.infer<typeof ZCourseSlug>;
|
||||
|
||||
/**
|
||||
* Generate a kebab-case slug from a free-form title. Does not enforce uniqueness;
|
||||
* callers must resolve collisions against the target namespace (e.g. per-course).
|
||||
|
||||
Reference in New Issue
Block a user