Skip to content

Latest commit

 

History

History
548 lines (403 loc) · 10.9 KB

File metadata and controls

548 lines (403 loc) · 10.9 KB

API Reference

Complete API documentation for the Research Organization Template.

Table of Contents


Authentication

Server Actions

login(formData: FormData)

Authenticate a user with email and password.

Location: src/app/(withoutNavbar)/login/actions.ts

Parameters:

  • email (string) - User email address
  • password (string) - User password

Returns:

{ error?: string }

Example:

const formData = new FormData()
formData.append('email', 'user@example.com')
formData.append('password', 'password123')

const result = await login(formData)
if (result.error) {
  console.error(result.error)
}

Errors:

  • "Email and password are required" - Missing credentials
  • "Please check your email and confirm your account" - Email not confirmed
  • "Invalid email or password" - Authentication failed

signup(formData: FormData)

Create a new user account.

Location: src/app/(withoutNavbar)/signup/actions.ts

Parameters:

  • email (string) - User email address
  • password (string) - User password (min 8 characters)

Returns:

{ error?: string }

Example:

const formData = new FormData()
formData.append('email', 'newuser@example.com')
formData.append('password', 'securepassword123')

const result = await signup(formData)

Note: New users are automatically assigned the member role.


API Routes

POST /api/auth/signout

Sign out the current user.

Returns:

  • Redirects to /login

Example:

await fetch('/api/auth/signout', { method: 'POST' })

Projects

Server Actions

saveProject(formData: FormData)

Create or update a project. Admin/Manager only.

Location: src/app/(withoutNavbar)/dashboard/admin/projects/actions.ts

Parameters:

  • id (string, optional) - Project ID for updates
  • title (string) - Project title
  • slug (string) - URL-friendly slug (unique)
  • description (string) - Project description
  • project_type (string) - Type: research_paper, software, experiment, dataset, other
  • category_id (string, optional) - Category UUID
  • status (string) - active, completed, or archived
  • tags (string) - Comma-separated tags
  • github_url (string, optional) - GitHub repository URL
  • demo_url (string, optional) - Demo URL
  • paper_url (string, optional) - Research paper URL
  • documentation_url (string, optional) - Documentation URL
  • authors (string) - Comma-separated author names
  • publication_venue (string, optional) - Publication venue
  • publication_year (number, optional) - Publication year
  • doi (string, optional) - DOI
  • published_at (string, optional) - ISO date string for publishing

Returns:

{ error?: string, projectId?: string }

Example:

const formData = new FormData()
formData.append('title', 'My Research Project')
formData.append('slug', 'my-research-project')
formData.append('description', 'A groundbreaking research project')
formData.append('project_type', 'research_paper')
formData.append('status', 'active')
formData.append('tags', 'AI, Machine Learning, Research')
formData.append('published_at', new Date().toISOString())

const result = await saveProject(formData)

Errors:

  • "Not authenticated" - User not logged in
  • "Only admins and managers can manage projects" - Insufficient permissions
  • "Project with this slug already exists" - Duplicate slug

deleteProject(projectId: string)

Delete a project. Admin/Manager only.

Location: src/app/(withoutNavbar)/dashboard/admin/projects/actions.ts

Parameters:

  • projectId (string) - Project UUID

Returns:

{ error?: string }

Community

Server Actions

createPost(params: CreatePostParams)

Create a new discussion post. Authenticated users only.

Location: src/app/api/community/posts/actions.ts

Parameters:

interface CreatePostParams {
  title: string
  content: string
  categoryId?: string | null
  projectId?: string | null
}

Returns:

{ error?: string, success?: boolean, postId?: string }

Example:

const result = await createPost({
  title: 'Discussion about AI',
  content: 'What are your thoughts on...',
  categoryId: 'category-uuid',
  projectId: 'project-uuid' // optional
})

createComment(params: CreateCommentParams)

Create a comment on a post or reply to a comment. Authenticated users only.

Location: src/app/api/community/comments/actions.ts

Parameters:

interface CreateCommentParams {
  postId: string
  parentCommentId?: string // For nested replies
  content: string
}

Returns:

{ error?: string, success?: boolean, comment?: Comment }

Example:

// Top-level comment
const result = await createComment({
  postId: 'post-uuid',
  content: 'Great post!'
})

// Reply to comment
const reply = await createComment({
  postId: 'post-uuid',
  parentCommentId: 'comment-uuid',
  content: 'I agree!'
})

vote(params: VoteParams)

Vote on a post or comment. Authenticated users only.

Location: src/app/api/community/vote/actions.ts

Parameters:

interface VoteParams {
  targetId: string // Post or comment ID
  type: 'post' | 'comment'
  voteType: 1 | -1 // 1 for upvote, -1 for downvote
}

Returns:

{ error?: string, voteScore?: number, userVote?: 1 | -1 | null }

Example:

// Upvote a post
const result = await vote({
  targetId: 'post-uuid',
  type: 'post',
  voteType: 1
})

// Downvote a comment
const result = await vote({
  targetId: 'comment-uuid',
  type: 'comment',
  voteType: -1
})

Behavior:

  • Clicking the same vote again removes the vote (toggles off)
  • Clicking the opposite vote changes the vote
  • Vote scores are automatically recalculated

Admin

Server Actions

updateUserRole(userId: string, newRole: UserRole)

Update a user's role. Admin only.

Location: src/app/(withoutNavbar)/dashboard/admin/roles/actions.ts

Parameters:

  • userId (string) - User UUID
  • newRole (string) - 'admin', 'manager', or 'member'

Returns:

{ error?: string }

Example:

const result = await updateUserRole('user-uuid', 'manager')
if (result.error) {
  console.error(result.error)
}

Errors:

  • "Not authenticated" - User not logged in
  • "Only admins can change user roles" - Insufficient permissions
  • "Invalid role" - Role not in allowed list
  • "You cannot remove your own admin role" - Self-protection

API Routes

GET /api/admin/users

List all users with their roles. Admin only.

Returns:

{
  users: Array<{
    id: string
    role: 'admin' | 'manager' | 'member'
    created_at: string
  }>
}

Example:

const response = await fetch('/api/admin/users', {
  headers: {
    'Cookie': document.cookie
  }
})
const data = await response.json()

Status Codes:

  • 200 - Success
  • 401 - Not authenticated
  • 403 - Not admin

Utilities

API Routes

POST /api/send

Send an email via the contact form. Optional - requires Resend API key.

Location: src/app/api/send/route.ts

Request Body:

{
  firstname: string
  lastname: string
  email: string
  message: string
}

Returns:

{ data?: EmailResponse, error?: string }

Example:

const response = await fetch('/api/send', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    firstname: 'John',
    lastname: 'Doe',
    email: 'john@example.com',
    message: 'Hello!'
  })
})

Environment Variables:

  • RESEND_API_KEY - Required for email functionality

Note: Update the recipient email in src/app/api/send/route.ts (line 18).


Type Definitions

All types are available in src/utils/types.ts:

import {
  Project,
  DiscussionPost,
  DiscussionComment,
  Category,
  UserRole,
  ProjectStatus,
  VoteType
} from '@/utils/types'

Constants

Application constants are in src/utils/constants.ts:

import {
  ROLES,
  PROJECT_STATUS,
  PROJECT_TYPES,
  ROUTES,
  VALIDATION
} from '@/utils/constants'

Error Handling

All API endpoints and server actions return errors in a consistent format:

{ error: string }

Common Error Messages:

  • "Not authenticated" - User must be logged in
  • "Forbidden" - User lacks required permissions
  • "Not found" - Resource doesn't exist
  • "Invalid input" - Validation failed

Authentication

Most endpoints require authentication. The application uses:

  1. Supabase Auth - Session-based authentication
  2. Server-side verification - All protected routes verify auth server-side
  3. Role-based access - Admin/Manager/Member roles enforced

Getting Current User:

import { createClient } from '@/utils/supabase/server'

const supabase = await createClient()
const { data: { user } } = await supabase.auth.getUser()

if (!user) {
  // Not authenticated
}

Checking Roles:

import { requireRole, getUserRole } from '@/utils/roles'

const role = await getUserRole(user.id)
const isAdmin = await requireRole(user.id, ['admin'])

Rate Limiting

Currently, the application relies on Supabase's built-in rate limiting:

  • Free tier: 500 requests per second per project
  • Pro tier: Higher limits

For production, consider implementing additional rate limiting for:

  • Email sending
  • Vote actions
  • Comment creation

Security Best Practices

  1. Always verify authentication - Check user on server-side
  2. Verify roles server-side - Never trust client-side role checks
  3. Use RLS policies - Database-level security
  4. Validate input - Sanitize user input
  5. Use parameterized queries - Supabase handles this automatically
  6. HTTPS only - All deployments use HTTPS

Testing

Manual Testing

Use the browser console or tools like Postman:

// Example: Create a post
const formData = new FormData()
formData.append('title', 'Test Post')
formData.append('content', 'Test content')

const response = await fetch('/api/community/posts', {
  method: 'POST',
  body: formData
})

Server Actions

Test server actions directly:

import { createPost } from '@/app/api/community/posts/actions'

const result = await createPost({
  title: 'Test',
  content: 'Test content'
})

Next Steps

  • Review Setup Guide for database configuration
  • Check Deployment Guide for production setup
  • Explore the codebase for implementation details

Need help? Open an issue on GitHub or check the documentation.