REFACTORED - Flatten portfolio category routes to /portfolio/[slug]

Merge the category and project routes under a single /portfolio/[slug]
segment via resolvePortfolioSlug (category wins over project on a slug
clash). Removes the /portfolio/category/... prefix from links, redirect,
and sitemap. Adds resolver integration tests.
This commit is contained in:
moh
2026-09-20 18:53:48 +02:00
parent 5b019052b1
commit 3f96abc60f
9 changed files with 133 additions and 136 deletions
+24
View File
@@ -285,6 +285,30 @@ export const getPublishedPortfolioProjectBySlug = cache(async function (slug: st
return mapProject(project);
});
export type ResolvedPortfolioSlug =
| { kind: "category"; category: PortfolioCategoryView }
| { kind: "project"; project: PortfolioProjectView }
| null;
/**
* Resolves a `/portfolio/[slug]` segment to either a category or a project.
* Categories take precedence so `/portfolio/web` shows the category listing;
* a project slug only wins when no active category shares that slug.
*/
export async function resolvePortfolioSlug(slug: string): Promise<ResolvedPortfolioSlug> {
const category = await getActivePortfolioCategoryBySlug(slug);
if (category) {
return { kind: "category", category };
}
const project = await getPublishedPortfolioProjectBySlug(slug);
if (project) {
return { kind: "project", project };
}
return null;
}
export async function getAdminPortfolioProjectById(id: string) {
const project = await db.query.portfolioProject.findFirst({
where: eq(portfolioProject.id, id),