project-structure
This skill should be used when working with the JKKN COE Next.js project folder structure, including understanding where to place files, creating new modules, navigating the codebase, or following arc
SKILL.md.claude/skills/coe-project-structure/SKILL.md
GitHubProject Structure Guide
This skill provides comprehensive guidance for navigating and working with the JKKN COE project folder structure.
When to Use This Skill
Use this skill when:
- Understanding the overall project organization
- Determining where to place new files (components, services, pages, types, etc.)
- Creating new CRUD modules or features
- Following established architectural patterns
- Navigating the Next.js 15 App Router structure
- Understanding the 5-layer architecture (Types → Services → Hooks → Components → Pages)
Project Architecture Overview
The JKKN COE application follows a modular, layered architecture using Next.js 15 App Router with TypeScript, Supabase backend, and Shadcn UI components.
Core Architectural Principles
- App Router Structure: Uses Next.js 15 App Router with route groups for organization
- 5-Layer Architecture: Types → Services → Hooks → Components → Pages
- Role-Based Access Control (RBAC): Permission-based routing and component rendering
- Server-Side First: Default to Server Components, use Client Components only when needed
- Modular Design: Each entity (courses, degrees, students, etc.) follows consistent patterns
Project Folder Structure
Root Level Organization
jkkncoe/
├── .claude/ # Claude Code configuration and skills
│ └── skills/ # Custom skills for development acceleration
├── .cursor/ # Cursor IDE configuration
│ └── rules/ # Development standards and conventions
├── app/ # Next.js 15 App Router (main application code)
│ ├── coe/ # Route group for protected pages
│ ├── api/ # API route handlers
│ ├── auth/ # Authentication pages (login, callback)
│ └── layout.tsx # Root layout
├── components/ # Reusable UI components
│ ├── common/ # Shared components across modules
│ ├── layout/ # Layout components (header, sidebar, footer)
│ ├── ui/ # Shadcn UI primitives
│ └── users/ # User-specific components
├── context/ # React Context providers
├── hooks/ # Custom React hooks
├── lib/ # Utilities, configurations, and helpers
│ ├── constants/ # Application constants
│ └── utils/ # Utility functions
├── services/ # Business logic and data access layer
├── store/ # State management (Redux if needed)
├── styles/ # Global styles and Tailwind CSS
├── supabase/ # Supabase configuration
│ └── migrations/ # Database migration files
├── types/ # TypeScript type definitions
└── public/ # Static assets
Detailed Directory Structure
For comprehensive folder structure details, file naming conventions, and usage examples, refer to:
Where to Place Files
1. Pages and Routes (app/)
Structure:
app/
├── coe/ # Protected routes
│ ├── courses/ # Entity module
│ │ └── page.tsx # Main page component
│ ├── degrees/
│ ├── students/
│ └── layout.tsx # Authenticated layout wrapper
├── api/ # API routes
│ ├── courses/
│ │ ├── route.ts # GET, POST endpoints
│ │ └── [id]/
│ │ └── route.ts # PUT, DELETE endpoints
└── login/ # Public routes
└── page.tsx
When to create new files:
- New entity page:
app/coe/[entity-name]/page.tsx - Nested route:
app/coe/[entity]/[sub-route]/page.tsx - API endpoint:
app/api/[entity]/route.ts - Dynamic API route:
app/api/[entity]/[id]/route.ts
Naming Convention:
- Use
kebab-casefor directory names - Always
page.tsxfor route pages - Always
route.tsfor API handlers - Always
layout.tsxfor layout components
2. Components (components/)
Structure:
components/
├── common/ # Shared across modules
│ ├── data-table.tsx # Reusable table component
│ ├── file-upload.tsx # Upload component
│ └── protected-route.tsx # Auth guard
├── layout/ # App-wide layout
│ ├── app-header.tsx
│ ├── app-sidebar.tsx
│ └── app-footer.tsx
├── ui/ # Shadcn UI primitives
│ ├── button.tsx
│ ├── input.tsx
│ └── sheet.tsx
└── [entity]/ # Entity-specific components
├── [entity]-form.tsx
└── [entity]-table.tsx
When to create new files:
- Reusable component:
components/common/[component-name].tsx - Entity-specific component:
components/[entity]/[component-name].tsx - UI primitive: Import from Shadcn, don't create manually
Component Guidelines:
- Default to Server Components
- Add
"use client"only when using:- Event handlers (onClick, onChange)
- Browser APIs (localStorage, window)
- State (useState, useReducer, useContext)
- Effects (useEffect)
- Client-only libraries
3. Services (services/)
Structure:
services/
├── courses-service.ts # Course data access
├── degrees-service.ts # Degree data access
├── students-service.ts # Student data access
└── auth-service.ts # Authentication service
When to create new files:
- New entity service:
services/[entity]-service.ts - Shared utility service:
services/[utility]-service.ts
Service Responsibilities:
- Database queries using Supabase client
- Data transformation and validation
- Business logic execution
- Error handling and logging
4. Types (types/)
Structure:
types/
├── courses.ts # Course type definitions
├── degrees.ts # Degree type definitions
├── students.ts # Student type definitions
├── auth.ts # Authentication types
└── index.ts # Re-export all types
When to create new files:
- New entity types:
types/[entity].ts - Shared types:
types/[domain].ts
Type Naming Convention:
- Use PascalCase for type/interface names
- Prefix with entity name for clarity
- Example:
CourseFormData,DegreeCreatePayload
5. Hooks (hooks/)
Structure:
hooks/
├── use-auth.ts # Authentication hook
├── use-toast.ts # Toast notification hook
├── use-courses.ts # Course data fetching hook
└── use-form-validation.ts # Form validation hook
When to create new files:
- New custom hook:
hooks/use-[functionality].ts - Always prefix with
use-(React convention)
Hook Responsibilities:
- Encapsulate reusable stateful logic
- Handle data fetching with loading/error states
- Manage form state and validation
- Integrate with context providers
6. Utilities (lib/)
Structure:
lib/
├── supabase-server.ts # Server-side Supabase client
├── utils.ts # General utilities
├── constants/
│ ├── routes.ts # Route constants
│ └── permissions.ts # Permission constants
└── utils/
├── format.ts # Formatting utilities
└── validation.ts # Validation helpers
When to create new files:
- New utility module:
lib/utils/[utility-name].ts - New constants:
lib/constants/[constant-group].ts
7. Context Providers (context/)
Structure:
context/
├── auth-context.tsx # Authentication context
├── theme-context.tsx # Theme provider
└── permissions-context.tsx # Permissions context
When to create new files:
- New context:
context/[context-name]-context.tsx - Only create when state needs to be shared across multiple components
8. Database Migrations (supabase/migrations/)
Structure:
supabase/
└── migrations/
├── 20240101120000_create_users.sql
├── 20240102130000_create_courses.sql
└── 20240103140000_add_rbac_tables.sql
When to create new files:
- Schema changes: Always create a new migration file
- Naming:
[timestamp]_[description].sql - Generate timestamp:
date +%Y%m%d%H%M%S
Creating New Modules (5-Layer Architecture)
When creating a new entity module (e.g., "courses", "students"), follow this order:
Layer 1: Types (types/[entity].ts)
export interface Course {
id: string
course_code: string
course_title: string
credits: number
// ... other fields
}
export interface CourseFormData {
course_code: string
course_title: string
credits: string
// ... form fields
}
Layer 2: Services (services/[entity]-service.ts)
import { getSupabaseServer } from '@/lib/supabase-server'
import type { Course } from '@/types/courses'
export async function getCourses() {
const supabase = getSupabaseServer()
const { data, error } = await supabase
.from('courses')
.select('*')
if (error) throw error
return data as Course[]
}
Layer 3: Hooks (hooks/use-[entity].ts)
'use client'
import { useState, useEffect } from 'react'
import type { Course } from '@/types/courses'
export function useCourses() {
const [courses, setCourses] = useState<Course[]>([])
const [loading, setLoading] = useState(true)
useEffect(() => {
// Fetch courses
}, [])
return { courses, loading }
}
Layer 4: Components (app/coe/[entity]/page.tsx)
'use client'
import { useState } from 'react'
import { Sheet, SheetContent } from '@/components/ui/sheet'
// ... other imports
export default function CoursesPage() {
// Component implementation
}
Layer 5: API Routes (app/api/[entity]/route.ts)
import { NextRequest, NextResponse } from 'next/server'
import { getSupabaseServer } from '@/lib/supabase-server'
export async function GET() {
// GET handler
}
export async function POST(req: NextRequest) {
// POST handler
}
Navigation and File Discovery
Finding Files by Purpose
Authentication:
- Auth context:
context/auth-context.tsx - Login page:
app/login/page.tsx - Auth callback:
app/auth/callback/route.ts - Middleware:
middleware.ts(root level)
RBAC System:
- Permission checks:
components/common/protected-route.tsx - Role management page:
app/coe/roles/page.tsx - User roles API:
app/api/user-roles/route.ts
Entity CRUD:
- Page:
app/coe/[entity]/page.tsx - API:
app/api/[entity]/route.ts - Types:
types/[entity].ts - Service:
services/[entity]-service.ts
UI Components:
- Shadcn primitives:
components/ui/ - Layout components:
components/layout/ - Shared components:
components/common/
Search Patterns
Use these patterns to quickly find files:
# Find all entity pages
**/coe/*/page.tsx
# Find all API routes
**/api/*/route.ts
# Find all type definitions
types/*.ts
# Find all services
services/*-service.ts
# Find specific component
components/**/*-[name].tsx
Best Practices
- Consistent Naming: Follow
kebab-casefor directories,PascalCasefor components/types - Colocation: Keep related files close (e.g., entity-specific components with entity)
- Single Responsibility: Each file should have one clear purpose
- Import Paths: Use
@/alias for absolute imports from root - Server/Client Split: Default to Server Components, add
"use client"only when needed - Type Safety: Always define types in
types/directory before implementing - API Structure: Use RESTful conventions (GET/POST in route.ts, PUT/DELETE in [id]/route.ts)
Common Tasks
Creating a New Entity CRUD Page
- Define types:
types/[entity].ts - Create API routes:
app/api/[entity]/route.tsandapp/api/[entity]/[id]/route.ts - Create page:
app/coe/[entity]/page.tsx - Add to sidebar: Update
components/layout/app-sidebar.tsx - Test and verify: Check RBAC, validation, error handling
Adding a New Utility Function
- Create file:
lib/utils/[utility-name].ts - Export from:
lib/utils.ts(if general purpose) - Import using:
@/lib/utils/[utility-name]
Adding a New Component
- Determine scope: Common, layout, entity-specific, or UI primitive?
- Create file:
components/[category]/[component-name].tsx - Use PascalCase: For component function name
- Add
"use client": Only if needed
Additional Resources
For detailed folder structure visualization and comprehensive file listings, see:
- references/folder-structure.md - Complete directory tree and file descriptions