Files
thrillwiki_django_no_react/.agent/workflows/new-feature.md
pacnpal 1adba1b804 lol
2026-01-02 07:58:58 -05:00

7.4 KiB

description
description
Implement a full-stack feature across Django backend and Nuxt frontend

New Feature Workflow

Implement a complete feature spanning the Django backend and Nuxt frontend.

Planning Phase

Before writing any code, create an implementation plan:

1. Feature Definition

  • Goal: What problem does this feature solve?
  • User Stories: Who uses it and how?
  • Acceptance Criteria: How do we know it's done?

2. Technical Scope

  • Backend Changes: Models, APIs, permissions
  • Frontend Changes: Pages, components, state
  • Data Flow: How data moves between layers

3. Implementation Order

Always implement in this order:

  1. Database/Models - Foundation first
  2. API Endpoints - Backend logic
  3. Frontend Components - UI building blocks
  4. Frontend Pages - Assembled views
  5. Integration - Wire it all together
  6. Tests - Verify everything works

Implementation Steps

Step 1: Backend - Models

# Create or modify models
# Remember: Inherit from BaseModel, add proper indexes

class NewFeature(BaseModel):
    # Fields
    name = models.CharField(max_length=255)
    # ... other fields
    
    class Meta:
        ordering = ['-created_at']

Run migrations:

python manage.py makemigrations
python manage.py migrate

Step 2: Backend - Serializers

# backend/apps/[app]/serializers.py

class NewFeatureSerializer(serializers.ModelSerializer):
    class Meta:
        model = NewFeature
        fields = ['id', 'name', 'created_at', 'updated_at']
        read_only_fields = ['id', 'created_at', 'updated_at']

class NewFeatureDetailSerializer(NewFeatureSerializer):
    # Extended fields for detail view
    related_data = RelatedSerializer(many=True, read_only=True)
    
    class Meta(NewFeatureSerializer.Meta):
        fields = NewFeatureSerializer.Meta.fields + ['related_data']

Step 3: Backend - API Views

# backend/apps/[app]/views.py

class NewFeatureViewSet(viewsets.ModelViewSet):
    queryset = NewFeature.objects.all()
    serializer_class = NewFeatureSerializer
    permission_classes = [IsAuthenticatedOrReadOnly]
    
    def get_queryset(self):
        return NewFeature.objects.select_related(
            # Add related models
        ).prefetch_related(
            # Add many-to-many or reverse relations
        )
    
    def get_serializer_class(self):
        if self.action == 'retrieve':
            return NewFeatureDetailSerializer
        return NewFeatureSerializer

Step 4: Backend - URLs

# backend/apps/[app]/urls.py
router.register('new-features', NewFeatureViewSet, basename='new-feature')

Step 5: Backend - Tests

# backend/apps/[app]/tests/test_new_feature.py

class TestNewFeatureAPI(APITestCase):
    def test_list_features(self):
        response = self.client.get('/api/v1/new-features/')
        self.assertEqual(response.status_code, 200)
    
    def test_create_feature_authenticated(self):
        self.client.force_authenticate(user=self.user)
        response = self.client.post('/api/v1/new-features/', {'name': 'Test'})
        self.assertEqual(response.status_code, 201)

Step 6: Frontend - Types

// frontend/types/newFeature.ts

export interface NewFeature {
  id: string
  name: string
  createdAt: string
  updatedAt: string
}

export interface NewFeatureDetail extends NewFeature {
  relatedData: RelatedItem[]
}

Step 7: Frontend - Composables

// frontend/composables/useNewFeatures.ts

export function useNewFeatures() {
  const api = useApi()
  
  async function getFeatures(params?: Record<string, any>) {
    return api<PaginatedResponse<NewFeature>>('/new-features/', { params })
  }
  
  async function getFeature(id: string) {
    return api<NewFeatureDetail>(`/new-features/${id}/`)
  }
  
  async function createFeature(data: Partial<NewFeature>) {
    return api<NewFeature>('/new-features/', {
      method: 'POST',
      body: data
    })
  }
  
  return { getFeatures, getFeature, createFeature }
}

Step 8: Frontend - Components

Create necessary components following component patterns:

<!-- frontend/components/entity/NewFeatureCard.vue -->
<script setup lang="ts">
import type { NewFeature } from '~/types'

defineProps<{
  feature: NewFeature
}>()
</script>

<template>
  <Card interactive>
    <div class="p-4">
      <h3 class="font-semibold">{{ feature.name }}</h3>
      <!-- Additional content -->
    </div>
  </Card>
</template>

Step 9: Frontend - Pages

<!-- frontend/pages/new-features/index.vue -->
<script setup lang="ts">
definePageMeta({
  // middleware: ['auth'], // if needed
})

useSeoMeta({
  title: 'New Features | ThrillWiki',
})

const { data, pending, error } = await useAsyncData('new-features', () =>
  useNewFeatures().getFeatures()
)
</script>

<template>
  <PageContainer>
    <h1 class="text-3xl font-bold mb-8">New Features</h1>
    
    <div v-if="pending" class="grid grid-cols-1 md:grid-cols-3 gap-6">
      <Skeleton v-for="i in 6" :key="i" class="h-48" />
    </div>
    
    <div v-else-if="data?.results" class="grid grid-cols-1 md:grid-cols-3 gap-6">
      <NewFeatureCard 
        v-for="feature in data.results" 
        :key="feature.id" 
        :feature="feature" 
      />
    </div>
    
    <EmptyState v-else title="No features found" />
  </PageContainer>
</template>

Step 10: Integration Testing

Test the full flow:

  1. API Test: Verify endpoints with curl or API client
  2. Component Test: Test components in isolation
  3. E2E Test: Test complete user journey
// frontend/tests/e2e/newFeature.spec.ts
import { test, expect } from '@playwright/test'

test('user can view new features', async ({ page }) => {
  await page.goto('/new-features')
  await expect(page.locator('h1')).toContainText('New Features')
})

test('authenticated user can create feature', async ({ page }) => {
  // Login first
  await page.goto('/auth/login')
  // ... login steps
  
  await page.goto('/new-features/create')
  await page.fill('input[name="name"]', 'Test Feature')
  await page.click('button[type="submit"]')
  
  await expect(page).toHaveURL(/\/new-features\//)
})

Feature Checklist

Backend

  • Models created with proper fields and indexes
  • Migrations created and applied
  • Serializers handle validation
  • ViewSet has proper permissions
  • Queries are optimized
  • URLs registered
  • Unit tests pass

Frontend

  • Types defined
  • Composables created for API calls
  • Components follow design system
  • Pages have proper SEO meta
  • Loading states implemented
  • Error states handled
  • Responsive design verified
  • Keyboard accessible

Integration

  • Data flows correctly between backend and frontend
  • Authentication/authorization works
  • Error handling covers edge cases
  • Performance is acceptable

Output Summary

After completing the feature:

## Feature: [Feature Name]

### Backend
- Model: `apps/[app]/models.py` - NewFeature
- API: `/api/v1/new-features/`
- Permissions: [describe]

### Frontend  
- Page: `/new-features` (list), `/new-features/[id]` (detail)
- Components: NewFeatureCard, NewFeatureForm
- Composable: useNewFeatures

### Tests
- Backend: X tests passing
- Frontend: X tests passing
- E2E: X tests passing

### Notes
- [Any important implementation notes]
- [Known limitations]
- [Future improvements]