| name | category-management |
| description | Manage blog categories including CRUD operations, slug generation, and category assignment. Use when working with categories, category forms, slugs, or organizing blog content by category. |
Category Management
Overview
This skill helps you work with blog category management features. Categories organize blog posts and include automatic slug generation from titles.
Key Files and Components
Category Pages
src/app/admin/categories/page.tsx- Category listing pagesrc/app/admin/categories/create/page.tsx- Create new category pagesrc/app/admin/categories/edit/page.tsx- Edit existing category pagesrc/app/admin/categories/category-form.tsx- Main category form component
Domain & Infrastructure
src/domains/category.ts- Category model and typessrc/infrastructure/das/categories.das.ts- Category data access servicesrc/models/CreateCategoryModel.ts- Create category modelsrc/models/UpdateCategoryModel.ts- Update category model
GraphQL Integration
src/infrastructure/graphQL/queries/categories/get-categories.ts- Fetch categoriessrc/infrastructure/graphQL/queries/categories/get-blog-category-ids.ts- Fetch category IDssrc/infrastructure/graphQL/graphql-client.ts- Apollo client setup
Category Structure
A category includes:
- id: Unique identifier (GUID)
- name: Category display name
- slug: URL-friendly identifier (auto-generated)
- description: Optional category description
- rowVersion: For optimistic locking
Slug Generation
The project uses the slugify package for automatic slug generation:
import slugify from 'slugify';
const slug = slugify(name, {
lower: true,
strict: true,
trim: true
});
Slugs are:
- Lowercase
- Hyphen-separated
- URL-safe (special characters removed)
- Automatically generated from the name field
API Integration
Categories support both REST and GraphQL:
REST API Endpoints
GET /categories- List all categoriesGET /categories/:id- Get single categoryPOST /categories- Create new categoryPUT /categories/:id- Update existing categoryDELETE /categories/:id- Delete category
GraphQL Queries
GET_CATEGORIES- Fetch all categories with postsGET_BLOG_CATEGORY_IDS- Fetch category IDs for blog post filtering
All API calls require Bearer token authentication.
Common Tasks
Creating a Category
- User enters category name
- Slug is auto-generated from name
- Optional description can be added
- Submit creates category via REST API
- Navigate back to category list
Editing a Category
- Fetch existing category by ID
- Populate form with current data
- Allow name, slug, and description edits
- Include rowVersion for optimistic locking
- Submit updates category via REST API
- Navigate back to category list
Listing Categories
- Fetch categories from REST API or GraphQL
- Display in table or grid format
- Show name, slug, and action buttons
- Support edit and delete operations
Category Selection
When assigning categories to blog posts:
- Fetch all categories
- Display in dropdown/select component
- Store selected categoryId with post
Data Access Patterns
Using REST API
import { getApiUrl, authenticatedFetch } from '@/config/api.config';
// Fetch categories
const response = await authenticatedFetch(
getApiUrl('/categories'),
token
);
const data = await response.json();
Using GraphQL
import { graphqlClient } from '@/infrastructure/graphQL/graphql-client';
import { GET_CATEGORIES } from '@/infrastructure/graphQL/queries/categories/get-categories';
const { data } = await graphqlClient.query({
query: GET_CATEGORIES
});
Best Practices
- Always generate slugs from names automatically
- Validate uniqueness of slugs before submission
- Handle rowVersion for update operations
- Check authentication before API calls
- Show loading states during data fetching
- Handle errors gracefully with user feedback
- Use TypeScript types from domain models
- Cache category lists where appropriate (Apollo handles this for GraphQL)
TypeScript Types
Always use the domain types:
import type { CategoryModel } from '@/domains/category';
import type { CreateCategoryModel } from '@/models/CreateCategoryModel';
import type { UpdateCategoryModel } from '@/models/UpdateCategoryModel';
Debugging Tips
If you encounter issues:
- Verify slug generation is working correctly
- Check API endpoints are reachable
- Validate authentication token
- Review GraphQL query syntax
- Check Apollo cache for stale data
- Verify rowVersion matches for updates
- Test category assignment in blog posts
Integration with Blog Posts
Categories are referenced in blog posts:
- Blog posts have a
categoryIdfield - Categories can have multiple posts
- Use category data for filtering and organization
- Display category name with blog post metadata
Example Workflow
When implementing category features:
- Read category domain model
- Review existing category-form.tsx
- Check API configuration (REST and GraphQL)
- Test slug generation
- Implement changes following patterns
- Validate with TypeScript
- Test CRUD operations in dev server