@smicolon/ai-kit 0.3.2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +73 -40
  2. package/dist/index.js +312 -127
  3. package/package.json +5 -5
  4. package/.claude-plugin/marketplace.json +0 -369
  5. package/packs/architect/CHANGELOG.md +0 -17
  6. package/packs/architect/README.md +0 -58
  7. package/packs/architect/agents/system-architect.md +0 -768
  8. package/packs/architect/commands/diagram-create.md +0 -300
  9. package/packs/better-auth/.mcp.json +0 -14
  10. package/packs/better-auth/CHANGELOG.md +0 -26
  11. package/packs/better-auth/README.md +0 -125
  12. package/packs/better-auth/agents/auth-architect.md +0 -278
  13. package/packs/better-auth/commands/auth-provider-add.md +0 -265
  14. package/packs/better-auth/commands/auth-setup.md +0 -298
  15. package/packs/better-auth/skills/auth-security/SKILL.md +0 -425
  16. package/packs/better-auth/skills/better-auth-patterns/SKILL.md +0 -455
  17. package/packs/dev-loop/CHANGELOG.md +0 -69
  18. package/packs/dev-loop/README.md +0 -155
  19. package/packs/dev-loop/commands/cancel-dev.md +0 -21
  20. package/packs/dev-loop/commands/dev-loop.md +0 -72
  21. package/packs/dev-loop/commands/dev-plan.md +0 -351
  22. package/packs/dev-loop/hooks/hooks.json +0 -15
  23. package/packs/dev-loop/hooks/stop-hook.sh +0 -178
  24. package/packs/dev-loop/scripts/setup-dev-loop.sh +0 -194
  25. package/packs/dev-loop/skills/tdd-planner/SKILL.md +0 -249
  26. package/packs/dev-loop/skills/tdd-planner/references/framework-patterns.md +0 -874
  27. package/packs/dev-loop/skills/tdd-planner/references/good-example.md +0 -260
  28. package/packs/dev-loop/skills/tdd-planner/references/plan-template.md +0 -275
  29. package/packs/django/CHANGELOG.md +0 -39
  30. package/packs/django/README.md +0 -92
  31. package/packs/django/agents/django-architect.md +0 -182
  32. package/packs/django/agents/django-builder.md +0 -250
  33. package/packs/django/agents/django-feature-based.md +0 -420
  34. package/packs/django/agents/django-reviewer.md +0 -253
  35. package/packs/django/agents/django-tester.md +0 -230
  36. package/packs/django/commands/api-endpoint.md +0 -285
  37. package/packs/django/commands/model-create.md +0 -178
  38. package/packs/django/commands/test-generate.md +0 -325
  39. package/packs/django/rules/migrations.md +0 -138
  40. package/packs/django/rules/models.md +0 -167
  41. package/packs/django/rules/serializers.md +0 -126
  42. package/packs/django/rules/services.md +0 -131
  43. package/packs/django/rules/tests.md +0 -140
  44. package/packs/django/rules/views.md +0 -102
  45. package/packs/django/skills/import-convention-enforcer/SKILL.md +0 -226
  46. package/packs/django/skills/import-convention-enforcer/patterns/django-imports.md +0 -343
  47. package/packs/django/skills/migration-safety-checker/SKILL.md +0 -375
  48. package/packs/django/skills/model-entity-validator/SKILL.md +0 -298
  49. package/packs/django/skills/performance-optimizer/SKILL.md +0 -447
  50. package/packs/django/skills/red-phase-verifier/SKILL.md +0 -180
  51. package/packs/django/skills/security-first-validator/SKILL.md +0 -435
  52. package/packs/django/skills/test-coverage-advisor/SKILL.md +0 -394
  53. package/packs/django/skills/test-validity-checker/SKILL.md +0 -194
  54. package/packs/failure-log/CHANGELOG.md +0 -20
  55. package/packs/failure-log/README.md +0 -168
  56. package/packs/failure-log/commands/failure-add.md +0 -106
  57. package/packs/failure-log/commands/failure-list.md +0 -89
  58. package/packs/failure-log/hooks/hooks.json +0 -16
  59. package/packs/failure-log/hooks/scripts/inject-failures.sh +0 -64
  60. package/packs/failure-log/skills/failure-log-manager/SKILL.md +0 -164
  61. package/packs/flutter/CHANGELOG.md +0 -19
  62. package/packs/flutter/README.md +0 -170
  63. package/packs/flutter/agents/flutter-architect.md +0 -166
  64. package/packs/flutter/agents/flutter-builder.md +0 -303
  65. package/packs/flutter/agents/release-manager.md +0 -355
  66. package/packs/flutter/commands/fastlane-setup.md +0 -188
  67. package/packs/flutter/commands/flutter-build.md +0 -90
  68. package/packs/flutter/commands/flutter-deploy.md +0 -133
  69. package/packs/flutter/commands/flutter-test.md +0 -117
  70. package/packs/flutter/commands/signing-setup.md +0 -209
  71. package/packs/flutter/hooks/hooks.json +0 -17
  72. package/packs/flutter/skills/fastlane-knowledge/SKILL.md +0 -193
  73. package/packs/flutter/skills/flutter-architecture/SKILL.md +0 -127
  74. package/packs/flutter/skills/store-publishing/SKILL.md +0 -163
  75. package/packs/hono/CHANGELOG.md +0 -19
  76. package/packs/hono/README.md +0 -143
  77. package/packs/hono/agents/hono-architect.md +0 -240
  78. package/packs/hono/agents/hono-builder.md +0 -285
  79. package/packs/hono/agents/hono-reviewer.md +0 -279
  80. package/packs/hono/agents/hono-tester.md +0 -346
  81. package/packs/hono/commands/middleware-create.md +0 -223
  82. package/packs/hono/commands/project-init.md +0 -306
  83. package/packs/hono/commands/route-create.md +0 -153
  84. package/packs/hono/commands/rpc-client.md +0 -263
  85. package/packs/hono/skills/cloudflare-bindings/SKILL.md +0 -408
  86. package/packs/hono/skills/hono-patterns/SKILL.md +0 -309
  87. package/packs/hono/skills/rpc-typesafe/SKILL.md +0 -388
  88. package/packs/hono/skills/zod-validation/SKILL.md +0 -332
  89. package/packs/nestjs/CHANGELOG.md +0 -29
  90. package/packs/nestjs/README.md +0 -75
  91. package/packs/nestjs/agents/nestjs-architect.md +0 -402
  92. package/packs/nestjs/agents/nestjs-builder.md +0 -301
  93. package/packs/nestjs/agents/nestjs-tester.md +0 -437
  94. package/packs/nestjs/commands/module-create.md +0 -369
  95. package/packs/nestjs/rules/controllers.md +0 -92
  96. package/packs/nestjs/rules/dto.md +0 -124
  97. package/packs/nestjs/rules/entities.md +0 -102
  98. package/packs/nestjs/rules/services.md +0 -106
  99. package/packs/nestjs/skills/barrel-export-manager/SKILL.md +0 -389
  100. package/packs/nestjs/skills/import-convention-enforcer/SKILL.md +0 -365
  101. package/packs/nextjs/CHANGELOG.md +0 -36
  102. package/packs/nextjs/README.md +0 -76
  103. package/packs/nextjs/agents/frontend-tester.md +0 -680
  104. package/packs/nextjs/agents/frontend-visual.md +0 -820
  105. package/packs/nextjs/agents/nextjs-architect.md +0 -331
  106. package/packs/nextjs/agents/nextjs-modular.md +0 -433
  107. package/packs/nextjs/commands/component-create.md +0 -398
  108. package/packs/nextjs/rules/api-routes.md +0 -129
  109. package/packs/nextjs/rules/components.md +0 -106
  110. package/packs/nextjs/rules/hooks.md +0 -132
  111. package/packs/nextjs/skills/accessibility-validator/SKILL.md +0 -445
  112. package/packs/nextjs/skills/import-convention-enforcer/SKILL.md +0 -399
  113. package/packs/nextjs/skills/react-form-validator/SKILL.md +0 -569
  114. package/packs/nuxtjs/CHANGELOG.md +0 -30
  115. package/packs/nuxtjs/README.md +0 -56
  116. package/packs/nuxtjs/agents/frontend-tester.md +0 -680
  117. package/packs/nuxtjs/agents/frontend-visual.md +0 -820
  118. package/packs/nuxtjs/agents/nuxtjs-architect.md +0 -537
  119. package/packs/nuxtjs/commands/component-create.md +0 -223
  120. package/packs/nuxtjs/rules/components.md +0 -101
  121. package/packs/nuxtjs/rules/composables.md +0 -118
  122. package/packs/nuxtjs/rules/server-routes.md +0 -127
  123. package/packs/nuxtjs/skills/accessibility-validator/SKILL.md +0 -183
  124. package/packs/nuxtjs/skills/import-convention-enforcer/SKILL.md +0 -196
  125. package/packs/nuxtjs/skills/veevalidate-form-validator/SKILL.md +0 -190
  126. package/packs/onboard/CHANGELOG.md +0 -22
  127. package/packs/onboard/README.md +0 -103
  128. package/packs/onboard/agents/onboard-guide.md +0 -118
  129. package/packs/onboard/commands/onboard.md +0 -313
  130. package/packs/onboard/skills/onboard-context-provider/SKILL.md +0 -98
  131. package/packs/tanstack-router/CHANGELOG.md +0 -30
  132. package/packs/tanstack-router/README.md +0 -113
  133. package/packs/tanstack-router/agents/tanstack-architect.md +0 -173
  134. package/packs/tanstack-router/agents/tanstack-builder.md +0 -360
  135. package/packs/tanstack-router/agents/tanstack-tester.md +0 -454
  136. package/packs/tanstack-router/commands/form-create.md +0 -313
  137. package/packs/tanstack-router/commands/query-create.md +0 -263
  138. package/packs/tanstack-router/commands/route-create.md +0 -190
  139. package/packs/tanstack-router/commands/table-create.md +0 -413
  140. package/packs/tanstack-router/skills/ai-patterns/SKILL.md +0 -370
  141. package/packs/tanstack-router/skills/db-patterns/SKILL.md +0 -346
  142. package/packs/tanstack-router/skills/devtools-patterns/SKILL.md +0 -415
  143. package/packs/tanstack-router/skills/form-patterns/SKILL.md +0 -425
  144. package/packs/tanstack-router/skills/pacer-patterns/SKILL.md +0 -341
  145. package/packs/tanstack-router/skills/query-patterns/SKILL.md +0 -359
  146. package/packs/tanstack-router/skills/router-patterns/SKILL.md +0 -285
  147. package/packs/tanstack-router/skills/store-patterns/SKILL.md +0 -351
  148. package/packs/tanstack-router/skills/table-patterns/SKILL.md +0 -531
  149. package/packs/tanstack-router/skills/tanstack-conventions/SKILL.md +0 -428
  150. package/packs/tanstack-router/skills/virtual-patterns/SKILL.md +0 -490
  151. package/packs/worktree/CHANGELOG.md +0 -45
  152. package/packs/worktree/README.md +0 -219
  153. package/packs/worktree/commands/wt.md +0 -93
  154. package/packs/worktree/scripts/wt.sh +0 -957
  155. package/packs/worktree/skills/worktree-manager/SKILL.md +0 -113
@@ -1,126 +0,0 @@
1
- ---
2
- paths:
3
- - "**/serializers.py"
4
- - "**/serializers/*.py"
5
- ---
6
-
7
- # Django Serializer Standards
8
-
9
- ## Structure
10
-
11
- ```python
12
- import users.models as _users_models
13
- from rest_framework import serializers
14
-
15
- class UserSerializer(serializers.ModelSerializer):
16
- """Read serializer for User."""
17
-
18
- class Meta:
19
- model = _users_models.User
20
- fields = ['id', 'email', 'first_name', 'last_name', 'created_at']
21
- read_only_fields = ['id', 'created_at']
22
-
23
-
24
- class CreateUserSerializer(serializers.Serializer):
25
- """Write serializer for creating User."""
26
-
27
- email = serializers.EmailField()
28
- password = serializers.CharField(write_only=True, min_length=8)
29
- first_name = serializers.CharField(max_length=100)
30
-
31
- def validate_email(self, value):
32
- if _users_models.User.objects.filter(email=value).exists():
33
- raise serializers.ValidationError("Email already exists")
34
- return value.lower()
35
- ```
36
-
37
- ## Import Pattern
38
-
39
- ```python
40
- import users.models as _users_models
41
- from rest_framework import serializers
42
- ```
43
-
44
- ## Rules
45
-
46
- - Separate read/write serializers when needed
47
- - All validation in serializer, not view
48
- - Use `validate_<field>` for field-level validation
49
- - Use `validate` for cross-field validation
50
- - Never expose sensitive fields (password, tokens)
51
-
52
- ## Naming Convention
53
-
54
- - Read serializers: `{Model}Serializer`
55
- - Create serializers: `Create{Model}Serializer`
56
- - Update serializers: `Update{Model}Serializer`
57
- - List serializers (minimal): `{Model}ListSerializer`
58
-
59
- ## Validation Examples
60
-
61
- ### Field-Level Validation
62
-
63
- ```python
64
- class CreateUserSerializer(serializers.Serializer):
65
- email = serializers.EmailField()
66
- password = serializers.CharField(write_only=True)
67
-
68
- def validate_email(self, value):
69
- """Normalize and validate email."""
70
- value = value.lower().strip()
71
- if _users_models.User.objects.filter(email=value).exists():
72
- raise serializers.ValidationError("Email already exists")
73
- return value
74
-
75
- def validate_password(self, value):
76
- """Validate password strength."""
77
- if len(value) < 8:
78
- raise serializers.ValidationError("Password must be at least 8 characters")
79
- if not any(c.isdigit() for c in value):
80
- raise serializers.ValidationError("Password must contain a digit")
81
- return value
82
- ```
83
-
84
- ### Cross-Field Validation
85
-
86
- ```python
87
- class PasswordChangeSerializer(serializers.Serializer):
88
- old_password = serializers.CharField(write_only=True)
89
- new_password = serializers.CharField(write_only=True)
90
- confirm_password = serializers.CharField(write_only=True)
91
-
92
- def validate(self, data):
93
- if data['new_password'] != data['confirm_password']:
94
- raise serializers.ValidationError({
95
- "confirm_password": "Passwords do not match"
96
- })
97
- if data['old_password'] == data['new_password']:
98
- raise serializers.ValidationError({
99
- "new_password": "New password must be different"
100
- })
101
- return data
102
- ```
103
-
104
- ## Nested Serializers
105
-
106
- ```python
107
- class OrderItemSerializer(serializers.ModelSerializer):
108
- class Meta:
109
- model = _models.OrderItem
110
- fields = ['id', 'product', 'quantity', 'price']
111
-
112
- class OrderSerializer(serializers.ModelSerializer):
113
- items = OrderItemSerializer(many=True, read_only=True)
114
- total = serializers.DecimalField(max_digits=10, decimal_places=2, read_only=True)
115
-
116
- class Meta:
117
- model = _models.Order
118
- fields = ['id', 'user', 'items', 'total', 'created_at']
119
- ```
120
-
121
- ## Forbidden Patterns
122
-
123
- - Business logic in serializers (use services)
124
- - Direct database queries (use services)
125
- - Exposing sensitive fields
126
- - Using ModelSerializer for write operations with complex logic
@@ -1,131 +0,0 @@
1
- ---
2
- paths:
3
- - "**/services.py"
4
- - "**/services/*.py"
5
- ---
6
-
7
- # Django Service Layer Standards
8
-
9
- ## Purpose
10
-
11
- Services contain business logic. Views delegate to services.
12
-
13
- ## Structure
14
-
15
- ```python
16
- import users.models as _users_models
17
- from django.db import transaction
18
-
19
- class UserService:
20
- """
21
- Business logic for User operations.
22
- All methods are static or class methods.
23
- """
24
-
25
- @staticmethod
26
- @transaction.atomic
27
- def create_user(data: dict) -> _users_models.User:
28
- """
29
- Create a new user with validation.
30
-
31
- Args:
32
- data: Validated user data from serializer
33
-
34
- Returns:
35
- Created User instance
36
-
37
- Raises:
38
- ValidationError: If email already exists
39
- """
40
- # Business logic here
41
- user = _users_models.User.objects.create(**data)
42
- # Side effects (emails, notifications)
43
- return user
44
- ```
45
-
46
- ## Requirements
47
-
48
- - All database operations use `@transaction.atomic`
49
- - Methods have type hints
50
- - Docstrings explain purpose, args, returns, raises
51
- - Static methods preferred (no instance state)
52
- - Import pattern: `import app.models as _models`
53
-
54
- ## Forbidden Patterns
55
-
56
- - Service methods calling views
57
- - Circular service dependencies
58
- - HTTP-specific code (request, response)
59
- - Direct print statements (use logging)
60
- - Catching broad exceptions without re-raising
61
-
62
- ## Method Patterns
63
-
64
- ### Query Methods
65
-
66
- ```python
67
- @staticmethod
68
- def get_by_id(user_id: uuid.UUID) -> _users_models.User:
69
- """Get user by ID or raise DoesNotExist."""
70
- return _users_models.User.objects.get(id=user_id, is_deleted=False)
71
-
72
- @staticmethod
73
- def get_active_users() -> QuerySet[_users_models.User]:
74
- """Get all active users."""
75
- return _users_models.User.objects.filter(is_active=True, is_deleted=False)
76
- ```
77
-
78
- ### Mutation Methods
79
-
80
- ```python
81
- @staticmethod
82
- @transaction.atomic
83
- def update_user(user_id: uuid.UUID, data: dict) -> _users_models.User:
84
- """Update user fields."""
85
- user = _users_models.User.objects.select_for_update().get(id=user_id)
86
- for key, value in data.items():
87
- setattr(user, key, value)
88
- user.save()
89
- return user
90
-
91
- @staticmethod
92
- @transaction.atomic
93
- def soft_delete_user(user_id: uuid.UUID) -> None:
94
- """Soft delete a user."""
95
- _users_models.User.objects.filter(id=user_id).update(is_deleted=True)
96
- ```
97
-
98
- ## Error Handling
99
-
100
- ```python
101
- import logging
102
- from django.core.exceptions import ValidationError
103
-
104
- logger = logging.getLogger(__name__)
105
-
106
- class UserService:
107
- @staticmethod
108
- @transaction.atomic
109
- def create_user(data: dict) -> _users_models.User:
110
- try:
111
- user = _users_models.User.objects.create(**data)
112
- logger.info(f"Created user: {user.id}")
113
- return user
114
- except IntegrityError as e:
115
- logger.error(f"Failed to create user: {e}")
116
- raise ValidationError("User with this email already exists")
117
- ```
118
-
119
- ## Testing Services
120
-
121
- Services should be the primary unit test target:
122
-
123
- ```python
124
- @pytest.mark.django_db
125
- class TestUserService:
126
- def test_create_user_success(self):
127
- data = {'email': 'test@example.com', 'password': 'secure123'}
128
- user = UserService.create_user(data)
129
- assert user.id is not None
130
- assert user.email == 'test@example.com'
131
- ```
@@ -1,140 +0,0 @@
1
- ---
2
- paths:
3
- - "**/test*.py"
4
- - "**/tests/**/*.py"
5
- - "**/*_test.py"
6
- ---
7
-
8
- # Django Test Standards
9
-
10
- ## Coverage Target: 90%+
11
-
12
- ## Structure
13
-
14
- ```python
15
- import pytest
16
- import users.models as _users_models
17
- import users.services as _users_services
18
- from rest_framework.test import APIClient
19
- from rest_framework import status
20
-
21
- @pytest.mark.django_db
22
- class TestUserService:
23
- """Tests for UserService."""
24
-
25
- def test_create_user_success(self):
26
- """Test successful user creation."""
27
- data = {'email': 'test@example.com', 'password': 'secure123'}
28
-
29
- user = _users_services.UserService.create_user(data)
30
-
31
- assert user.id is not None
32
- assert user.email == 'test@example.com'
33
- assert user.created_at is not None
34
-
35
- def test_create_user_duplicate_email(self):
36
- """Test creation fails with duplicate email."""
37
- _users_models.User.objects.create(email='existing@example.com')
38
-
39
- with pytest.raises(ValidationError) as exc:
40
- _users_services.UserService.create_user({'email': 'existing@example.com'})
41
-
42
- assert 'email' in str(exc.value)
43
- ```
44
-
45
- ## Requirements
46
-
47
- - Use pytest, not unittest
48
- - Import pattern: `import app.models as _app_models`
49
- - Minimum 2 assertions per test
50
- - Test happy path AND error paths
51
- - Use factories for complex data (factory_boy)
52
- - Mark DB tests with `@pytest.mark.django_db`
53
-
54
- ## Test Categories
55
-
56
- 1. Unit tests (80%): Models, services, utilities
57
- 2. Integration tests (15%): API endpoints
58
- 3. Edge cases (5%): Boundaries, errors
59
-
60
- ## Forbidden Patterns
61
-
62
- - Tests without assertions
63
- - `assert True` or `assert obj` (meaningless)
64
- - Shared mutable state between tests
65
- - Skipped tests without explanation
66
-
67
- ## Test Naming
68
-
69
- ```python
70
- # Pattern: test_{method}_{scenario}_{expected_result}
71
- def test_create_user_success(self):
72
- def test_create_user_duplicate_email_raises_validation_error(self):
73
- def test_get_user_not_found_raises_does_not_exist(self):
74
- ```
75
-
76
- ## API Test Pattern
77
-
78
- ```python
79
- @pytest.mark.django_db
80
- class TestUserAPI:
81
- """API tests for User endpoints."""
82
-
83
- @pytest.fixture
84
- def client(self):
85
- return APIClient()
86
-
87
- @pytest.fixture
88
- def authenticated_client(self, user):
89
- client = APIClient()
90
- client.force_authenticate(user=user)
91
- return client
92
-
93
- def test_list_users_unauthenticated_returns_401(self, client):
94
- response = client.get('/api/users/')
95
- assert response.status_code == status.HTTP_401_UNAUTHORIZED
96
-
97
- def test_list_users_authenticated_returns_200(self, authenticated_client):
98
- response = authenticated_client.get('/api/users/')
99
- assert response.status_code == status.HTTP_200_OK
100
- assert 'results' in response.data
101
- ```
102
-
103
- ## Factory Pattern
104
-
105
- ```python
106
- import factory
107
- from factory.django import DjangoModelFactory
108
- import users.models as _users_models
109
-
110
- class UserFactory(DjangoModelFactory):
111
- class Meta:
112
- model = _users_models.User
113
-
114
- email = factory.Sequence(lambda n: f'user{n}@example.com')
115
- first_name = factory.Faker('first_name')
116
- last_name = factory.Faker('last_name')
117
- is_active = True
118
-
119
- # Usage in tests
120
- def test_list_users(self, authenticated_client):
121
- UserFactory.create_batch(5)
122
- response = authenticated_client.get('/api/users/')
123
- assert len(response.data['results']) == 5
124
- ```
125
-
126
- ## Fixtures
127
-
128
- ```python
129
- @pytest.fixture
130
- def user():
131
- return UserFactory()
132
-
133
- @pytest.fixture
134
- def admin_user():
135
- return UserFactory(is_staff=True, is_superuser=True)
136
-
137
- @pytest.fixture
138
- def product(user):
139
- return ProductFactory(owner=user)
140
- ```
@@ -1,102 +0,0 @@
1
- ---
2
- paths:
3
- - "**/views.py"
4
- - "**/views/*.py"
5
- - "**/viewsets.py"
6
- ---
7
-
8
- # Django View Standards
9
-
10
- ## Required Security
11
-
12
- EVERY view/viewset MUST have:
13
-
14
- ```python
15
- from rest_framework.permissions import IsAuthenticated
16
- from rest_framework.throttling import UserRateThrottle
17
-
18
- class YourViewSet(viewsets.ModelViewSet):
19
- # REQUIRED - No exceptions
20
- permission_classes = [IsAuthenticated]
21
- throttle_classes = [UserRateThrottle]
22
- ```
23
-
24
- ## Import Pattern
25
-
26
- ```python
27
- # CORRECT - Modular imports with aliases
28
- import users.models as _users_models
29
- import users.services as _users_services
30
- import users.serializers as _users_serializers
31
-
32
- # Usage
33
- queryset = _users_users_models.User.objects.filter(is_deleted=False)
34
- serializer_class = _users_users_serializers.UserSerializer
35
- ```
36
-
37
- ## View Structure
38
-
39
- ```python
40
- class UserViewSet(viewsets.ModelViewSet):
41
- permission_classes = [IsAuthenticated]
42
- throttle_classes = [UserRateThrottle]
43
-
44
- # Use service layer - no raw ORM in views
45
- def create(self, request):
46
- serializer = _users_serializers.CreateUserSerializer(data=request.data)
47
- serializer.is_valid(raise_exception=True)
48
- user = _users_users_services.UserService.create(serializer.validated_data)
49
- return Response(_users_users_serializers.UserSerializer(user).data, status=201)
50
- ```
51
-
52
- ## Forbidden Patterns
53
-
54
- - Views without permission_classes
55
- - Direct `request.data` access without serializer
56
- - ORM queries in view methods (use services)
57
- - `@api_view` without `@permission_classes`
58
- - Hardcoded status codes (use `status.HTTP_*`)
59
-
60
- ## Response Patterns
61
-
62
- ```python
63
- from rest_framework import status
64
- from rest_framework.response import Response
65
-
66
- # CORRECT
67
- return Response(data, status=status.HTTP_201_CREATED)
68
- return Response(status=status.HTTP_204_NO_CONTENT)
69
-
70
- # WRONG
71
- return Response(data, status=201) # Use named constants
72
- ```
73
-
74
- ## Error Handling
75
-
76
- ```python
77
- from rest_framework.exceptions import NotFound, PermissionDenied
78
-
79
- class UserViewSet(viewsets.ModelViewSet):
80
- def retrieve(self, request, pk=None):
81
- try:
82
- user = _users_users_services.UserService.get_by_id(pk)
83
- except _users_users_models.User.DoesNotExist:
84
- raise NotFound("User not found")
85
- return Response(_users_users_serializers.UserSerializer(user).data)
86
- ```
87
-
88
- ## Pagination
89
-
90
- Always use pagination for list views:
91
-
92
- ```python
93
- from rest_framework.pagination import PageNumberPagination
94
-
95
- class StandardPagination(PageNumberPagination):
96
- page_size = 20
97
- page_size_query_param = 'page_size'
98
- max_page_size = 100
99
-
100
- class UserViewSet(viewsets.ModelViewSet):
101
- pagination_class = StandardPagination
102
- ```