cc-codeconductor 1.4.2 → 1.5.0

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 (186) hide show
  1. package/README.md +37 -12
  2. package/dist/index.js +291 -109
  3. package/docs/generated/cli.md +8 -0
  4. package/package.json +1 -1
  5. package/presets/agy/README.md +1 -1
  6. package/presets/agy/hooks.json +1 -1
  7. package/presets/agy/scripts/invoke-hook.cjs +20 -5
  8. package/presets/agy/settings.json +1 -1
  9. package/presets/agy/skills/api-versioning/SKILL.md +394 -0
  10. package/presets/agy/skills/astro/SKILL.md +318 -0
  11. package/presets/agy/skills/auth-token-inspector/SKILL.md +30 -0
  12. package/presets/agy/skills/cc-pagespeed/SKILL.md +2 -3
  13. package/presets/agy/skills/code-review/SKILL.md +207 -0
  14. package/presets/agy/skills/django-orm/SKILL.md +460 -0
  15. package/presets/agy/skills/django-uv/SKILL.md +405 -0
  16. package/presets/agy/skills/drizzle-schema-architect/SKILL.md +50 -0
  17. package/presets/agy/skills/fastapi-pydantic-strict/SKILL.md +43 -0
  18. package/presets/agy/skills/jpa-nplusone-detector/SKILL.md +45 -0
  19. package/presets/agy/skills/jpa-postgres/SKILL.md +623 -0
  20. package/presets/agy/skills/livewire-alpine-bridge/SKILL.md +35 -0
  21. package/presets/agy/skills/nextjs-typescript/SKILL.md +390 -0
  22. package/presets/agy/skills/python/SKILL.md +611 -0
  23. package/presets/agy/skills/seo-analytics-injector/SKILL.md +43 -0
  24. package/presets/agy/skills/spring-auth-auditor/SKILL.md +29 -0
  25. package/presets/agy/skills/spring-boot-feature/SKILL.md +563 -0
  26. package/presets/agy/skills/spring-boot-testing-strategy/SKILL.md +475 -0
  27. package/presets/agy/skills/tailwind-responsive-auditor/SKILL.md +29 -0
  28. package/presets/agy/skills/tdd-mutation-tester/SKILL.md +27 -0
  29. package/presets/agy/workflows/cc-pagespeed.md +2 -3
  30. package/presets/agy/workflows/cc-review.md +31 -0
  31. package/presets/agy/workflows/cc-security.md +1 -1
  32. package/presets/claude/commands/cc/review.md +33 -0
  33. package/presets/claude/settings.json +2 -2
  34. package/presets/claude/skills/android/SKILL.md +1 -1
  35. package/presets/claude/skills/api-versioning/SKILL.md +1 -1
  36. package/presets/claude/skills/astro/SKILL.md +318 -0
  37. package/presets/claude/skills/auth-token-inspector/SKILL.md +30 -0
  38. package/presets/claude/skills/code-review/SKILL.md +207 -0
  39. package/presets/claude/skills/django-orm/SKILL.md +1 -1
  40. package/presets/claude/skills/django-testing/SKILL.md +1 -1
  41. package/presets/claude/skills/django-uv/SKILL.md +405 -0
  42. package/presets/claude/skills/drizzle-schema-architect/SKILL.md +50 -0
  43. package/presets/claude/skills/fastapi-pydantic-strict/SKILL.md +43 -0
  44. package/presets/claude/skills/jpa-nplusone-detector/SKILL.md +45 -0
  45. package/presets/claude/skills/jpa-postgres/SKILL.md +1 -1
  46. package/presets/claude/skills/livewire-alpine-bridge/SKILL.md +35 -0
  47. package/presets/claude/skills/nextjs-typescript/SKILL.md +390 -0
  48. package/presets/claude/skills/pagespeed-perf/SKILL.md +1 -1
  49. package/presets/claude/skills/python/SKILL.md +1 -1
  50. package/presets/claude/skills/python-django-stack/SKILL.md +1 -1
  51. package/presets/claude/skills/python-fastapi-stack/SKILL.md +1 -1
  52. package/presets/claude/skills/security/SKILL.md +1 -1
  53. package/presets/claude/skills/seo-analytics-injector/SKILL.md +43 -0
  54. package/presets/claude/skills/spring-auth-auditor/SKILL.md +29 -0
  55. package/presets/claude/skills/spring-boot-feature/SKILL.md +1 -1
  56. package/presets/claude/skills/spring-boot-kotlin/SKILL.md +1 -1
  57. package/presets/claude/skills/spring-boot-testing-strategy/SKILL.md +475 -0
  58. package/presets/claude/skills/sqlalchemy/SKILL.md +1 -1
  59. package/presets/claude/skills/tailwind-responsive-auditor/SKILL.md +29 -0
  60. package/presets/claude/skills/tdd-mutation-tester/SKILL.md +27 -0
  61. package/presets/claude/skills/testing-strategy/SKILL.md +1 -1
  62. package/presets/codex/skills/android/SKILL.md +1 -1
  63. package/presets/codex/skills/api-versioning/SKILL.md +1 -1
  64. package/presets/codex/skills/astro/SKILL.md +318 -0
  65. package/presets/codex/skills/auth-token-inspector/SKILL.md +30 -0
  66. package/presets/codex/skills/cc-openspec/SKILL.md +1 -1
  67. package/presets/codex/skills/cc-pagespeed/SKILL.md +2 -3
  68. package/presets/codex/skills/cc-review/SKILL.md +31 -0
  69. package/presets/codex/skills/cc-security/SKILL.md +1 -1
  70. package/presets/codex/skills/code-review/SKILL.md +207 -0
  71. package/presets/codex/skills/django-orm/SKILL.md +1 -1
  72. package/presets/codex/skills/django-testing/SKILL.md +1 -1
  73. package/presets/codex/skills/django-uv/SKILL.md +405 -0
  74. package/presets/codex/skills/drizzle-schema-architect/SKILL.md +50 -0
  75. package/presets/codex/skills/fastapi-pydantic-strict/SKILL.md +43 -0
  76. package/presets/codex/skills/jpa-nplusone-detector/SKILL.md +45 -0
  77. package/presets/codex/skills/jpa-postgres/SKILL.md +1 -1
  78. package/presets/codex/skills/livewire-alpine-bridge/SKILL.md +35 -0
  79. package/presets/codex/skills/nextjs-typescript/SKILL.md +390 -0
  80. package/presets/codex/skills/pagespeed-perf/SKILL.md +1 -1
  81. package/presets/codex/skills/python/SKILL.md +1 -1
  82. package/presets/codex/skills/python-django-stack/SKILL.md +1 -1
  83. package/presets/codex/skills/python-fastapi-stack/SKILL.md +1 -1
  84. package/presets/codex/skills/security-ai-llm/SKILL.md +43 -0
  85. package/presets/codex/skills/security-blue-team/SKILL.md +43 -0
  86. package/presets/codex/skills/security-cloud/SKILL.md +43 -0
  87. package/presets/codex/skills/security-crypto/SKILL.md +43 -0
  88. package/presets/codex/skills/security-exploit-dev/SKILL.md +45 -0
  89. package/presets/codex/skills/security-grc/SKILL.md +43 -0
  90. package/presets/codex/skills/security-incident-response/SKILL.md +45 -0
  91. package/presets/codex/skills/security-log-analysis/SKILL.md +43 -0
  92. package/presets/codex/skills/security-malware-analysis/SKILL.md +44 -0
  93. package/presets/codex/skills/security-mobile/SKILL.md +43 -0
  94. package/presets/codex/skills/security-network/SKILL.md +43 -0
  95. package/presets/codex/skills/security-ot-ics/SKILL.md +43 -0
  96. package/presets/codex/skills/security-recon/SKILL.md +45 -0
  97. package/presets/codex/skills/security-red-team/SKILL.md +44 -0
  98. package/presets/codex/skills/security-reverse-engineering/SKILL.md +44 -0
  99. package/presets/codex/skills/security-soc-automation/SKILL.md +43 -0
  100. package/presets/codex/skills/security-threat-hunting/SKILL.md +43 -0
  101. package/presets/codex/skills/security-vuln-assessment/SKILL.md +45 -0
  102. package/presets/codex/skills/security-web/SKILL.md +44 -0
  103. package/presets/codex/skills/seo-analytics-injector/SKILL.md +43 -0
  104. package/presets/codex/skills/spring-auth-auditor/SKILL.md +29 -0
  105. package/presets/codex/skills/spring-boot-feature/SKILL.md +2 -2
  106. package/presets/codex/skills/spring-boot-kotlin/SKILL.md +1 -1
  107. package/presets/codex/skills/spring-boot-testing-strategy/SKILL.md +475 -0
  108. package/presets/codex/skills/sqlalchemy/SKILL.md +1 -1
  109. package/presets/codex/skills/tailwind-responsive-auditor/SKILL.md +29 -0
  110. package/presets/codex/skills/tdd-mutation-tester/SKILL.md +27 -0
  111. package/presets/codex/skills/testing-strategy/SKILL.md +1 -1
  112. package/presets/cursor/commands/cc/openspec.md +1 -1
  113. package/presets/cursor/commands/cc/pagespeed.md +2 -3
  114. package/presets/cursor/commands/cc/review.md +31 -0
  115. package/presets/cursor/commands/cc/security.md +1 -1
  116. package/presets/cursor/skills/android/SKILL.md +1 -1
  117. package/presets/cursor/skills/api-versioning/SKILL.md +2 -1
  118. package/presets/cursor/skills/astro/SKILL.md +1 -1
  119. package/presets/cursor/skills/auth-token-inspector/SKILL.md +1 -1
  120. package/presets/cursor/skills/code-review/SKILL.md +1 -1
  121. package/presets/cursor/skills/django-orm/SKILL.md +3 -5
  122. package/presets/cursor/skills/django-testing/SKILL.md +1 -1
  123. package/presets/cursor/skills/django-uv/SKILL.md +1 -1
  124. package/presets/cursor/skills/drizzle-schema-architect/SKILL.md +1 -1
  125. package/presets/cursor/skills/fastapi-pydantic-strict/SKILL.md +1 -1
  126. package/presets/cursor/skills/jpa-nplusone-detector/SKILL.md +1 -1
  127. package/presets/cursor/skills/jpa-postgres/SKILL.md +2 -4
  128. package/presets/cursor/skills/livewire-alpine-bridge/SKILL.md +1 -1
  129. package/presets/cursor/skills/nextjs-typescript/SKILL.md +1 -1
  130. package/presets/cursor/skills/pagespeed-perf/SKILL.md +1 -1
  131. package/presets/cursor/skills/python/SKILL.md +6 -7
  132. package/presets/cursor/skills/python-django-stack/SKILL.md +1 -1
  133. package/presets/cursor/skills/python-fastapi-stack/SKILL.md +1 -1
  134. package/presets/cursor/skills/security/SKILL.md +1 -1
  135. package/presets/cursor/skills/seo-analytics-injector/SKILL.md +1 -1
  136. package/presets/cursor/skills/spring-auth-auditor/SKILL.md +1 -1
  137. package/presets/cursor/skills/spring-boot-feature/SKILL.md +2 -4
  138. package/presets/cursor/skills/spring-boot-kotlin/SKILL.md +1 -1
  139. package/presets/cursor/skills/spring-boot-testing-strategy/SKILL.md +1 -1
  140. package/presets/cursor/skills/sqlalchemy/SKILL.md +1 -1
  141. package/presets/cursor/skills/tailwind-responsive-auditor/SKILL.md +1 -1
  142. package/presets/cursor/skills/tdd-mutation-tester/SKILL.md +1 -1
  143. package/presets/gemini/commands/cc/openspec.toml +1 -1
  144. package/presets/gemini/commands/cc/pagespeed.toml +2 -3
  145. package/presets/gemini/commands/cc/review.toml +31 -0
  146. package/presets/gemini/commands/cc/security.toml +1 -1
  147. package/presets/opencode/README.md +45 -52
  148. package/presets/opencode/commands/cc-pagespeed.md +2 -3
  149. package/presets/opencode/commands/cc-review.md +31 -0
  150. package/presets/opencode/commands/cc-security.md +1 -1
  151. package/presets/opencode/opencode.jsonc +1 -1
  152. package/presets/opencode/skills/android/SKILL.md +1 -1
  153. package/presets/opencode/skills/api-versioning/SKILL.md +2 -1
  154. package/presets/opencode/skills/astro/SKILL.md +1 -1
  155. package/presets/opencode/skills/auth-token-inspector/SKILL.md +1 -1
  156. package/presets/opencode/skills/code-review/SKILL.md +1 -1
  157. package/presets/opencode/skills/django-orm/SKILL.md +3 -3
  158. package/presets/opencode/skills/django-testing/SKILL.md +1 -1
  159. package/presets/opencode/skills/django-uv/SKILL.md +1 -1
  160. package/presets/opencode/skills/drizzle-schema-architect/SKILL.md +1 -1
  161. package/presets/opencode/skills/fastapi-pydantic-strict/SKILL.md +1 -1
  162. package/presets/opencode/skills/jpa-nplusone-detector/SKILL.md +1 -1
  163. package/presets/opencode/skills/jpa-postgres/SKILL.md +2 -1
  164. package/presets/opencode/skills/livewire-alpine-bridge/SKILL.md +1 -1
  165. package/presets/opencode/skills/nextjs-typescript/SKILL.md +1 -1
  166. package/presets/opencode/skills/pagespeed-perf/SKILL.md +1 -1
  167. package/presets/opencode/skills/python/SKILL.md +6 -5
  168. package/presets/opencode/skills/python-django-stack/SKILL.md +1 -1
  169. package/presets/opencode/skills/python-fastapi-stack/SKILL.md +1 -1
  170. package/presets/opencode/skills/security/SKILL.md +1 -1
  171. package/presets/opencode/skills/seo-analytics-injector/SKILL.md +1 -1
  172. package/presets/opencode/skills/spring-auth-auditor/SKILL.md +1 -1
  173. package/presets/opencode/skills/spring-boot-feature/SKILL.md +2 -1
  174. package/presets/opencode/skills/spring-boot-kotlin/SKILL.md +1 -1
  175. package/presets/opencode/skills/spring-boot-testing-strategy/SKILL.md +1 -1
  176. package/presets/opencode/skills/sqlalchemy/SKILL.md +1 -1
  177. package/presets/opencode/skills/tailwind-responsive-auditor/SKILL.md +1 -1
  178. package/presets/opencode/skills/tdd-mutation-tester/SKILL.md +1 -1
  179. package/presets/seo-hotel/skills/astro-seo/SKILL.md +1 -1
  180. package/presets/seo-hotel/skills/geo-readiness/SKILL.md +1 -1
  181. package/presets/seo-hotel/skills/off-page/SKILL.md +1 -1
  182. package/presets/seo-hotel/skills/schema-validator/SKILL.md +1 -1
  183. package/presets/seo-hotel/skills/seo-audit/SKILL.md +1 -1
  184. package/presets/shared/invoke-hook.cjs +20 -5
  185. package/src/presets/models/roles.yml +28 -28
  186. package/src/presets/shared-skills.yml +58 -22
@@ -0,0 +1,405 @@
1
+ ---
2
+ id: django-uv
3
+ name: django-uv
4
+ description: >
5
+ Provides expert knowledge for building Django 5+ projects with UV as the package manager, domain-driven app structure, ruff for linting, and pytest-django for testing.
6
+
7
+ user-invokable: true
8
+ license: MIT
9
+ metadata:
10
+ author: lgzarturo
11
+ category: django
12
+
13
+ compatibility:
14
+ tools: [claude, codex, gemini, agy, opencode]
15
+ stacks:
16
+ languages: []
17
+ frameworks: []
18
+
19
+ risk:
20
+ level: medium
21
+ can_execute_shell: false
22
+ can_modify_files: true
23
+ requires_network: false
24
+
25
+ inputs: []
26
+
27
+ outputs: []
28
+
29
+ quality:
30
+ reviewed_by: codeconductor-core
31
+ version: 0.1.0
32
+ ---
33
+
34
+
35
+
36
+ # Django + UV
37
+
38
+ ## Project Setup with UV
39
+
40
+ UV replaces pip, pip-tools, virtualenv, and pyenv in a single binary. Always
41
+ use UV for dependency management.
42
+
43
+ ```bash
44
+ # Create project
45
+ uv init my-project
46
+ cd my-project
47
+
48
+ # Add Django and dependencies
49
+ uv add django psycopg[binary] djangorestframework django-environ
50
+
51
+ # Add dev dependencies
52
+ uv add --dev pytest pytest-django ruff factory-boy coverage
53
+
54
+ # Run management commands
55
+ uv run python manage.py migrate
56
+ uv run python manage.py runserver
57
+ ```
58
+
59
+ ### pyproject.toml Layout
60
+
61
+ ```toml
62
+ [project]
63
+ name = "my-project"
64
+ version = "0.1.0"
65
+ requires-python = ">=3.12"
66
+ dependencies = [
67
+ "django>=5.0",
68
+ "psycopg[binary]>=3.1",
69
+ "djangorestframework>=3.15",
70
+ "django-environ>=0.11",
71
+ ]
72
+
73
+ [project.optional-dependencies]
74
+ dev = [
75
+ "pytest>=8.0",
76
+ "pytest-django>=4.8",
77
+ "ruff>=0.4",
78
+ "factory-boy>=3.3",
79
+ "coverage>=7.4",
80
+ ]
81
+
82
+ [tool.ruff]
83
+ line-length = 88
84
+ target-version = "py312"
85
+
86
+ [tool.ruff.lint]
87
+ select = ["E", "F", "I", "N", "UP", "B", "SIM"]
88
+ ignore = ["E501"]
89
+
90
+ [tool.pytest.ini_options]
91
+ DJANGO_SETTINGS_MODULE = "config.settings.test"
92
+ python_files = ["test_*.py", "*_test.py"]
93
+ python_classes = ["Test*"]
94
+ python_functions = ["test_*"]
95
+
96
+ [tool.coverage.run]
97
+ source = ["."]
98
+ omit = ["*/migrations/*", "*/tests/*", "manage.py"]
99
+ ```
100
+
101
+ ## App Structure (Domain-Driven)
102
+
103
+ Organize by domain, not by technical layer. Each Django app owns its domain
104
+ entirely.
105
+
106
+ ```text
107
+ my_project/
108
+ config/
109
+ settings/
110
+ base.py — shared settings
111
+ dev.py — local overrides
112
+ test.py — test-specific settings
113
+ prod.py — production settings
114
+ urls.py
115
+ wsgi.py
116
+ apps/
117
+ users/
118
+ models.py
119
+ services.py — business logic, never in views
120
+ views.py — thin; delegates to services
121
+ serializers.py
122
+ admin.py
123
+ urls.py
124
+ tests/
125
+ test_models.py
126
+ test_services.py
127
+ test_views.py
128
+ factories.py
129
+ orders/
130
+ ...
131
+ manage.py
132
+ pyproject.toml
133
+ ```
134
+
135
+ ## Settings Split
136
+
137
+ ```python
138
+ # config/settings/base.py
139
+ from pathlib import Path
140
+ import environ
141
+
142
+ env = environ.Env()
143
+ BASE_DIR = Path(__file__).resolve().parent.parent.parent
144
+
145
+ SECRET_KEY = env("SECRET_KEY")
146
+ DEBUG = env.bool("DEBUG", default=False)
147
+
148
+ INSTALLED_APPS = [
149
+ "django.contrib.admin",
150
+ "django.contrib.auth",
151
+ "django.contrib.contenttypes",
152
+ "rest_framework",
153
+ "apps.users",
154
+ "apps.orders",
155
+ ]
156
+
157
+ DATABASES = {
158
+ "default": env.db("DATABASE_URL")
159
+ }
160
+ ```
161
+
162
+ ```python
163
+ # config/settings/test.py
164
+ from .base import * # noqa: F403
165
+
166
+ DATABASES = {
167
+ "default": {
168
+ "ENGINE": "django.db.backends.sqlite3",
169
+ "NAME": ":memory:",
170
+ }
171
+ }
172
+
173
+ # Never send real emails in tests
174
+ EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
175
+ ```
176
+
177
+ ## Models
178
+
179
+ ```python
180
+ # apps/users/models.py
181
+ import uuid
182
+ from django.db import models
183
+ from django.contrib.auth.models import AbstractUser
184
+
185
+
186
+ class User(AbstractUser):
187
+ id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
188
+ email = models.EmailField(unique=True)
189
+ bio = models.TextField(blank=True)
190
+ created_at = models.DateTimeField(auto_now_add=True)
191
+ updated_at = models.DateTimeField(auto_now=True)
192
+
193
+ USERNAME_FIELD = "email"
194
+ REQUIRED_FIELDS = ["username"]
195
+
196
+ class Meta:
197
+ ordering = ["-created_at"]
198
+
199
+ def __str__(self) -> str:
200
+ return self.email
201
+ ```
202
+
203
+ Rules:
204
+
205
+ - Use UUID primary keys — never expose sequential integer IDs in public APIs
206
+ - `auto_now_add` and `auto_now` for timestamps — never set manually
207
+ - Always define `__str__` — it appears in admin and error messages
208
+ - Use `blank=True` for optional strings (form validation), `null=True` only for
209
+ nullable FK/non-string fields
210
+
211
+ ## Service Layer
212
+
213
+ Business logic lives in `services.py`. Views are thin HTTP adapters.
214
+
215
+ ```python
216
+ # apps/users/services.py
217
+ from django.db import transaction
218
+ from django.contrib.auth.hashers import make_password
219
+ from .models import User
220
+
221
+
222
+ class UserService:
223
+
224
+ @staticmethod
225
+ def create_user(*, email: str, password: str, username: str) -> User:
226
+ if User.objects.filter(email=email).exists():
227
+ raise ValueError(f"Email {email!r} is already registered")
228
+
229
+ with transaction.atomic():
230
+ user = User.objects.create(
231
+ email=email,
232
+ username=username,
233
+ password=make_password(password),
234
+ )
235
+ return user
236
+
237
+ @staticmethod
238
+ def deactivate_user(*, user_id: str) -> User:
239
+ user = User.objects.get(id=user_id)
240
+ user.is_active = False
241
+ user.save(update_fields=["is_active", "updated_at"])
242
+ return user
243
+ ```
244
+
245
+ Rules:
246
+
247
+ - Use keyword-only arguments (`*` separator) in service methods — prevents
248
+ positional argument confusion
249
+ - Use `update_fields` in `save()` — avoids overwriting unintended fields and
250
+ reduces the UPDATE query scope
251
+ - Wrap multi-step writes in `transaction.atomic()`
252
+ - Never import from `views.py` in `services.py` — keep the dependency direction
253
+ strict: views → services → models
254
+
255
+ ## Views (DRF)
256
+
257
+ ```python
258
+ # apps/users/views.py
259
+ from rest_framework import status
260
+ from rest_framework.decorators import api_view, permission_classes
261
+ from rest_framework.permissions import IsAuthenticated
262
+ from rest_framework.request import Request
263
+ from rest_framework.response import Response
264
+
265
+ from .serializers import CreateUserSerializer, UserSerializer
266
+ from .services import UserService
267
+
268
+
269
+ @api_view(["POST"])
270
+ def create_user(request: Request) -> Response:
271
+ serializer = CreateUserSerializer(data=request.data)
272
+ serializer.is_valid(raise_exception=True)
273
+
274
+ user = UserService.create_user(**serializer.validated_data)
275
+ return Response(UserSerializer(user).data, status=status.HTTP_201_CREATED)
276
+
277
+
278
+ @api_view(["DELETE"])
279
+ @permission_classes([IsAuthenticated])
280
+ def deactivate_user(request: Request, user_id: str) -> Response:
281
+ UserService.deactivate_user(user_id=user_id)
282
+ return Response(status=status.HTTP_204_NO_CONTENT)
283
+ ```
284
+
285
+ ## Testing with pytest-django
286
+
287
+ ### Test Factories
288
+
289
+ ```python
290
+ # apps/users/tests/factories.py
291
+ import factory
292
+ from factory.django import DjangoModelFactory
293
+ from apps.users.models import User
294
+
295
+
296
+ class UserFactory(DjangoModelFactory):
297
+ class Meta:
298
+ model = User
299
+
300
+ email = factory.Sequence(lambda n: f"user{n}@example.com")
301
+ username = factory.Sequence(lambda n: f"user{n}")
302
+ password = factory.PostGenerationMethodCall("set_password", "testpass123")
303
+ is_active = True
304
+ ```
305
+
306
+ ### Service Tests
307
+
308
+ ```python
309
+ # apps/users/tests/test_services.py
310
+ import pytest
311
+ from apps.users.services import UserService
312
+
313
+
314
+ @pytest.mark.django_db
315
+ class TestUserService:
316
+
317
+ def test_create_user_succeeds_with_valid_data(self):
318
+ user = UserService.create_user(
319
+ email="new@example.com",
320
+ password="secure123",
321
+ username="newuser",
322
+ )
323
+
324
+ assert user.pk is not None
325
+ assert user.email == "new@example.com"
326
+ assert user.check_password("secure123")
327
+
328
+ def test_create_user_raises_when_email_exists(self, user_factory):
329
+ existing = user_factory(email="taken@example.com")
330
+
331
+ with pytest.raises(ValueError, match="already registered"):
332
+ UserService.create_user(
333
+ email=existing.email,
334
+ password="any",
335
+ username="other",
336
+ )
337
+ ```
338
+
339
+ ### View Tests
340
+
341
+ ```python
342
+ # apps/users/tests/test_views.py
343
+ import pytest
344
+ from django.urls import reverse
345
+
346
+
347
+ @pytest.mark.django_db
348
+ class TestCreateUser:
349
+
350
+ def test_returns_201_with_valid_payload(self, client):
351
+ response = client.post(
352
+ reverse("users:create"),
353
+ data={"email": "new@example.com", "password": "secure123", "username": "new"},
354
+ content_type="application/json",
355
+ )
356
+
357
+ assert response.status_code == 201
358
+ assert response.data["email"] == "new@example.com"
359
+
360
+ def test_returns_400_with_invalid_email(self, client):
361
+ response = client.post(
362
+ reverse("users:create"),
363
+ data={"email": "not-an-email", "password": "x", "username": "y"},
364
+ content_type="application/json",
365
+ )
366
+
367
+ assert response.status_code == 400
368
+
369
+ def test_returns_400_when_email_already_exists(self, client, user_factory):
370
+ user_factory(email="taken@example.com")
371
+
372
+ response = client.post(
373
+ reverse("users:create"),
374
+ data={"email": "taken@example.com", "password": "pass", "username": "z"},
375
+ content_type="application/json",
376
+ )
377
+
378
+ assert response.status_code == 400
379
+ ```
380
+
381
+ ### conftest.py
382
+
383
+ ```python
384
+ # conftest.py
385
+ import pytest
386
+ from pytest_factoryboy import register
387
+ from apps.users.tests.factories import UserFactory
388
+
389
+ register(UserFactory) # makes user_factory fixture available everywhere
390
+ ```
391
+
392
+ ## Linting
393
+
394
+ ```bash
395
+ # Check
396
+ uv run ruff check .
397
+
398
+ # Fix auto-fixable issues
399
+ uv run ruff check --fix .
400
+
401
+ # Format
402
+ uv run ruff format .
403
+ ```
404
+
405
+ Run ruff in CI on every pull request. Do not merge code that fails lint.
@@ -0,0 +1,50 @@
1
+ ---
2
+ id: drizzle-schema-architect
3
+ name: drizzle-schema-architect
4
+ description: >
5
+ Generates strictly typed Drizzle ORM schemas for PostgreSQL with indexes,
6
+ foreign keys, and Zod schema deduction.
7
+ user-invokable: true
8
+ license: MIT
9
+ metadata:
10
+ author: lgzarturo
11
+ category: database
12
+ compatibility:
13
+ tools: [claude, codex, gemini, agy, opencode]
14
+ stacks:
15
+ languages: [typescript, javascript]
16
+ frameworks: [nextjs, drizzle]
17
+ databases: [postgresql]
18
+ ---
19
+ # Drizzle Schema Architect
20
+
21
+ ## Core Principles
22
+
23
+ 1. **Strict Typing**: All table columns must be explicitly typed. Do not rely on loose implicit types.
24
+ 2. **PostgreSQL Focus**: Use pg-specific column types (e.g. `pgTable`, `uuid`, `timestamp`, `varchar`, `integer`).
25
+ 3. **Zod Validation Integration**: Always output Zod schemas inferred from Drizzle schemas using `drizzle-zod`'s `createInsertSchema` and `createSelectSchema`.
26
+
27
+ ## Schema Guidelines
28
+
29
+ - **Primary Keys**: Prefer UUIDs generated by `gen_random_uuid()` or autoincrementing integers depending on the table volume.
30
+ - **Indices**: Declare explicit indexes on foreign key columns and query filters.
31
+ - **Dates**: Always store timestamps using `timestamp('created_at', { withTimezone: true, mode: 'date' }).defaultNow().notNull()`.
32
+
33
+ ### Example Schema Pattern
34
+
35
+ ```typescript
36
+ import { pgTable, uuid, varchar, timestamp, index } from 'drizzle-orm/pg-core';
37
+ import { createInsertSchema, createSelectSchema } from 'drizzle-zod';
38
+
39
+ export const users = pgTable('users', {
40
+ id: uuid('id').defaultRandom().primaryKey(),
41
+ email: varchar('email', { length: 255 }).notNull().unique(),
42
+ name: varchar('name', { length: 255 }),
43
+ createdAt: timestamp('created_at', { withTimezone: true, mode: 'date' }).defaultNow().notNull(),
44
+ }, (table) => [
45
+ index('email_idx').on(table.email)
46
+ ]);
47
+
48
+ export const insertUserSchema = createInsertSchema(users);
49
+ export const selectUserSchema = createSelectSchema(users);
50
+ ```
@@ -0,0 +1,43 @@
1
+ ---
2
+ id: fastapi-pydantic-strict
3
+ name: fastapi-pydantic-strict
4
+ description: >
5
+ Enforces Pydantic v2 strict models, asynchronous dependency generators, and uv environment setup.
6
+ user-invokable: true
7
+ license: MIT
8
+ metadata:
9
+ author: lgzarturo
10
+ category: validation
11
+ compatibility:
12
+ tools: [claude, codex, gemini, agy, opencode]
13
+ stacks:
14
+ languages: [python]
15
+ frameworks: [fastapi, pydantic]
16
+ ---
17
+ # FastAPI Pydantic Strict
18
+
19
+ ## Core Principles
20
+
21
+ 1. **Pydantic v2 Model Configuration**: Always configure models with `model_config = ConfigDict(strict=True)` to enforce type correctness.
22
+ 2. **Async Dependencies**: Rely on async FastAPI dependency generators (`async def get_db()`) to handle context managers correctly.
23
+ 3. **Environment Management**: Use `uv` for lightning-fast package installs and lockfile consistency.
24
+
25
+ ## Code Blueprint
26
+
27
+ ```python
28
+ from fastapi import FastAPI, Depends
29
+ from pydantic import BaseModel, ConfigDict, Field
30
+
31
+ app = FastAPI()
32
+
33
+ class StrictUser(BaseModel):
34
+ model_config = ConfigDict(strict=True)
35
+
36
+ id: int
37
+ name: str = Field(..., min_length=2)
38
+ email: str
39
+
40
+ @app.post("/users", response_model=StrictUser)
41
+ async def create_user(user: StrictUser):
42
+ return user
43
+ ```
@@ -0,0 +1,45 @@
1
+ ---
2
+ id: jpa-nplusone-detector
3
+ name: jpa-nplusone-detector
4
+ description: >
5
+ Audits Hibernate database interactions to prevent N+1 query problems in JVM apps.
6
+ user-invokable: true
7
+ license: MIT
8
+ metadata:
9
+ author: lgzarturo
10
+ category: performance
11
+ compatibility:
12
+ tools: [claude, codex, gemini, agy, opencode]
13
+ stacks:
14
+ languages: [kotlin, java]
15
+ frameworks: [spring-boot, spring-data-jpa, hibernate]
16
+ ---
17
+ # JPA N+1 Query Detector
18
+
19
+ ## Core Principles
20
+
21
+ 1. **Hibernate Fetches**: Avoid lazy-loading relationships within loops or stream operations.
22
+ 2. **Batch Fetching & Joins**: Resolve N+1 issues by using `@EntityGraph` or `JOIN FETCH` inside custom JPQL queries.
23
+ 3. **Hibernate Statistics**: Enable Hibernate statistics in development to verify query counts.
24
+
25
+ ## Remediation Patterns
26
+
27
+ ### Ineffective Pattern (Triggers N+1 queries)
28
+ ```kotlin
29
+ val users = userRepository.findAll()
30
+ for (user in users) {
31
+ println(user.posts.size) // Post is loaded lazily for each user
32
+ }
33
+ ```
34
+
35
+ ### Remediation A: Using JOIN FETCH
36
+ ```kotlin
37
+ @Query("SELECT u FROM User u LEFT JOIN FETCH u.posts")
38
+ fun findAllWithPosts(): List<User>
39
+ ```
40
+
41
+ ### Remediation B: Using @EntityGraph
42
+ ```kotlin
43
+ @EntityGraph(attributePaths = ["posts"])
44
+ override fun findAll(): List<User>
45
+ ```