Skip to main content

Overview

This guide provides comprehensive information for developers who will maintain and extend RLink. It covers routine maintenance tasks, code organization, best practices, and common workflows.

Daily Development Workflow

Starting Work

1

Pull Latest Changes

git checkout main
git pull origin main
2

Create Feature Branch

git checkout -b feature/your-feature-name
# or
git checkout -b fix/bug-description
3

Install Dependencies (if needed)

npm install
4

Start Dev Server

npm run dev

Before Committing

Committing Changes

Follow conventional commit format:
# Format: <type>(<scope>): <description>

# Examples:
git commit -m "feat(cms): add project photo gallery"
git commit -m "fix(crm): resolve reservation linking bug"
git commit -m "docs: update API documentation"
git commit -m "refactor(iam): improve user query performance"
Commit Types:
  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • refactor: Code refactoring
  • test: Adding tests
  • chore: Maintenance tasks

Code Organization

Directory Structure Guidelines

Pattern: /api/{module}/{resource}/route.ts
app/api/
├── cms/
│   ├── projects/
│   │   ├── route.ts          # GET /api/cms/projects (list)
│   │   ├── [id]/
│   │   │   └── route.ts      # GET/PATCH/DELETE /api/cms/projects/[id]
│   │   └── export/
│   │       └── route.ts      # GET /api/cms/projects/export (CSV)
│   ├── articles/
│   └── careers/
├── crm/
└── iam/
Best Practice: Keep routes RESTful and predictable
Pattern: /lib/{module}/{purpose}.ts
lib/
├── cms/
│   ├── types.ts       # TypeScript types/interfaces
│   ├── queries.ts     # Database queries
│   ├── cache.ts       # Cache helpers
│   └── validation.ts  # Input validation schemas
├── crm/
├── iam/
├── db.ts             # Database connection
├── auth.ts           # Auth utilities
└── email/            # Email utilities
Best Practice: Keep business logic separate from API routes
Pattern: Organize by type or feature
components/
├── layout/
│   ├── Navbar.tsx
│   ├── Sidebar.tsx
│   └── Footer.tsx
├── tables/
│   ├── DataTable.tsx
│   ├── Pagination.tsx
│   └── Filters.tsx
├── modals/
│   ├── ConfirmDialog.tsx
│   └── FormModal.tsx
└── ui/               # shadcn/ui primitives
    ├── button.tsx
    ├── input.tsx
    └── ...
Best Practice: Reuse components, avoid duplication
Pattern: Separate files by concern
db/
├── schema.ts         # Application tables
├── auth-schema.ts    # Better Auth tables
└── types.ts          # Shared DB types
Best Practice: Use Drizzle ORM types, avoid raw SQL when possible

Database Management

Adding a New Table

1

Define Schema

Add to db/schema.ts:
import { pgTable, uuid, varchar, timestamp } from 'drizzle-orm/pg-core';

export const newTable = pgTable('new_table', {
  id: uuid('id').defaultRandom().primaryKey(),
  name: varchar('name', { length: 255 }).notNull(),
  createdAt: timestamp('created_at').defaultNow().notNull(),
  updatedAt: timestamp('updated_at').defaultNow().notNull(),
});
2

Generate Migration

npx drizzle-kit generate
Review generated SQL in drizzle/ directory
3

Apply Migration

# Development
npx drizzle-kit migrate

# Production
# Set production DATABASE_URL
DATABASE_URL="..." npx drizzle-kit migrate
4

Update Types

Create TypeScript types in lib/{module}/types.ts:
import { InferSelectModel, InferInsertModel } from 'drizzle-orm';
import { newTable } from '@/db/schema';

export type NewTableSelect = InferSelectModel<typeof newTable>;
export type NewTableInsert = InferInsertModel<typeof newTable>;

Modifying Existing Tables

NEVER modify production data directly! Always use migrations.
1

Update Schema

Modify the table definition in db/schema.ts
2

Generate Migration

npx drizzle-kit generate
3

Review Migration

Check the generated SQL carefully, especially for:
  • Data loss (dropping columns)
  • Constraint violations
  • Performance impact (adding indexes to large tables)
4

Test in Development

Apply migration to development database and test thoroughly
5

Apply to Production

Only after thorough testing

Adding New Features

Feature Development Checklist

Example: Adding a New CMS Feature

Let’s say you want to add “Testimonials” to the CMS:
1

1. Database Schema

// db/schema.ts
export const testimonials = pgTable('testimonials', {
  id: uuid('id').defaultRandom().primaryKey(),
  clientName: varchar('client_name', { length: 255 }).notNull(),
  projectId: uuid('project_id').references(() => projects.id),
  content: text('content').notNull(),
  rating: integer('rating').notNull(), // 1-5
  published: boolean('published').default(false),
  createdAt: timestamp('created_at').defaultNow().notNull(),
});
Generate and apply migration:
npx drizzle-kit generate
npx drizzle-kit migrate
2

2. Types

// lib/cms/types.ts
export type Testimonial = InferSelectModel<typeof testimonials>;
export type TestimonialInsert = InferInsertModel<typeof testimonials>;
3

3. API Routes

// app/api/cms/testimonials/route.ts
import { db } from '@/lib/db';
import { testimonials } from '@/db/schema';

export async function GET(request: Request) {
  try {
    const data = await db.select().from(testimonials);
    return Response.json(data);
  } catch (error) {
    return Response.json(
      { error: 'Failed to fetch testimonials' },
      { status: 500 }
    );
  }
}

export async function POST(request: Request) {
  try {
    const body = await request.json();
    const [result] = await db.insert(testimonials).values(body).returning();
    return Response.json(result, { status: 201 });
  } catch (error) {
    return Response.json(
      { error: 'Failed to create testimonial' },
      { status: 500 }
    );
  }
}
4

4. UI Components

// app/home/cms/testimonials/page.tsx
'use client';

import { useQuery } from '@tanstack/react-query';

export default function TestimonialsPage() {
  const { data, isLoading } = useQuery({
    queryKey: ['testimonials'],
    queryFn: async () => {
      const res = await fetch('/api/cms/testimonials');
      return res.json();
    },
  });
  
  if (isLoading) return <LoadingSkeleton />;
  
  return (
    <div>
      <h1>Testimonials</h1>
      {/* Table/list component here */}
    </div>
  );
}
5

5. Navigation

Add to sidebar navigation in layout component
6

6. Documentation

Update API reference and feature documentation

Performance Optimization

Database Query Optimization

// db/schema.ts
import { index } from 'drizzle-orm/pg-core';

export const projects = pgTable('projects', {
  // ... columns
}, (table) => {
  return {
    statusIdx: index('projects_status_idx').on(table.status),
    createdAtIdx: index('projects_created_at_idx').on(table.createdAt),
  };
});
// Bad - fetches all columns
const projects = await db.select().from(projectsTable);

// Good - fetches only needed columns
const projects = await db
  .select({
    id: projectsTable.id,
    name: projectsTable.name,
    status: projectsTable.status,
  })
  .from(projectsTable);
import { eq } from 'drizzle-orm';

const projectsWithGalleries = await db
  .select()
  .from(projects)
  .leftJoin(galleries, eq(projects.id, galleries.projectId))
  .limit(10);

Frontend Performance

const { data } = useQuery({
  queryKey: ['projects'],
  queryFn: fetchProjects,
  staleTime: 5 * 60 * 1000, // 5 minutes
  cacheTime: 10 * 60 * 1000, // 10 minutes
});
import dynamic from 'next/dynamic';

const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <LoadingSkeleton />,
  ssr: false, // If component doesn't need SSR
});
import Image from 'next/image';

<Image
  src="/uploads/large-image.jpg"
  alt="Project"
  width={800}
  height={600}
  quality={75}
  placeholder="blur"
  blurDataURL="data:image/..." // Optional blur placeholder
/>

Testing

Running Tests

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run specific test file
npm test -- users.test.ts

Writing Tests

Create tests in __tests__/ directory:
// __tests__/api/cms/projects.test.ts
import { GET } from '@/app/api/cms/projects/route';

describe('GET /api/cms/projects', () => {
  it('should return list of projects', async () => {
    const request = new Request('http://localhost:3000/api/cms/projects');
    const response = await GET(request);
    const data = await response.json();
    
    expect(response.status).toBe(200);
    expect(Array.isArray(data)).toBe(true);
  });
  
  it('should support pagination', async () => {
    const request = new Request('http://localhost:3000/api/cms/projects?page=1&limit=5');
    const response = await GET(request);
    const data = await response.json();
    
    expect(data.data.length).toBeLessThanOrEqual(5);
    expect(data.pagination).toBeDefined();
  });
});

Security Maintenance

Regular Security Tasks

Dependency Updates

1

Check for Updates

npm outdated
2

Update Dependencies

# Update all dependencies
npm update

# Or update specific package
npm update package-name
3

Test Thoroughly

Run tests and manually test critical features
4

Commit Changes

git commit -m "chore: update dependencies"

Monitoring & Maintenance

Weekly Tasks

Monthly Tasks

Quarterly Tasks

Debugging Tips

Database Issues

# Connect to database
psql "$DATABASE_URL"

# Useful queries
SELECT * FROM __drizzle_migrations ORDER BY created_at DESC;
SELECT COUNT(*) FROM users;
SELECT * FROM activity_logs WHERE created_at > NOW() - INTERVAL '1 hour';

# Check table sizes
SELECT 
  schemaname,
  tablename,
  pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;

API Debugging

Enable verbose logging in development:
// lib/db.ts
import { drizzle } from 'drizzle-orm/neon-http';
import { neon } from '@neondatabase/serverless';

const sql = neon(process.env.DATABASE_URL!);

export const db = drizzle(sql, {
  logger: process.env.NODE_ENV === 'development',
});

Frontend Debugging

Use React Query DevTools:
// app/layout.tsx
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <QueryClientProvider client={queryClient}>
          {children}
          <ReactQueryDevtools initialIsOpen={false} />
        </QueryClientProvider>
      </body>
    </html>
  );
}

Common Workflows

Fixing a Bug

1

Reproduce Locally

Understand the issue and reproduce in development
2

Create Fix Branch

git checkout -b fix/bug-description
3

Write Test

Write failing test that demonstrates the bug
4

Implement Fix

Fix the issue and verify test passes
5

Test Manually

Manually test the fix in development
6

Create PR

Push branch and create pull request

Deploying to Production

1

Merge to Main

After PR approval, merge to main branch
2

Automatic Deployment

Vercel automatically deploys main branch
3

Monitor Deployment

Watch deployment logs in Vercel dashboard
4

Verify Production

Test critical features in production
5

Rollback if Needed

If issues occur, promote previous deployment

Documentation

Keeping Documentation Updated

Documentation should be updated WITH code changes, not as an afterthought.
When to update docs:
  • New feature added → Update feature docs + API reference
  • API endpoint changed → Update API reference
  • Database schema changed → Update database schema docs
  • Bug fix → Update troubleshooting if applicable
  • Configuration changed → Update getting started / deployment

Documentation Standards

  • Use clear, concise language
  • Include code examples
  • Add warnings for breaking changes
  • Flag anything not verified against the repo with a clear Note or link to source
  • Keep changelog up to date

Best Practices Summary

Code Quality

  • Follow TypeScript best practices
  • Use ESLint and Prettier
  • Write meaningful comments
  • Keep functions small and focused

Git Workflow

  • Use feature branches
  • Write descriptive commit messages
  • Keep commits atomic
  • Rebase before merging

Testing

  • Write tests for new features
  • Test edge cases
  • Maintain high coverage
  • Run tests before committing

Security

  • Never commit secrets
  • Validate all inputs
  • Use parameterized queries
  • Keep dependencies updated

Getting Help

If you need assistance:
  1. Check Documentation: This documentation site
  2. Review Code: Look at existing implementations
  3. Search Issues: GitHub issues for similar problems
  4. Ask Team: Reach out to other developers
  5. External Resources:

Next Steps

Architecture

Understand the system design

REST API reference

Explore API endpoints

Troubleshooting

Solve common issues

Deployment

Deploy to production