[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6C0V798YK6E19TCB9HHW7F0":3,"skill-same:01M6C0V798YK6E19TCB9HHW7F0":91},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":47,"linkOnly":48,"markdownContent":49,"markdownBody":50,"frontMatter":51,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":14,"repositoryHtmlUrl":55,"repositoryHomepageUrl":6,"ownerHtmlUrl":56,"ownerBlogUrl":6,"ownerDescription":57,"updatedAt":58,"install":59,"resources":72},"01M6C0V798YK6E19TCB9HHW7F0","django-patterns",null,"Django 5.2 + DRF implementation patterns specific to Aprender Sistema v2 (modular apps\u002Fcore layout, HasPerm RBAC, read\u002Fwrite serializers, service layer, owner-scoped querysets). Use when writing a model, serializer, view\u002Fviewset, service, permission, or test in the v2 backend.","matheusnorjosa\u002Faprender_sistema","matheusnorjosa","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F117673804?v=4","01M6C0S19FG12BDFBTRWY9TTEQ","Matheus Norjosa","01M6C0S1DF0YB17TKGEYC70GSP",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa\u002Faprender_sistema\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fdjango-patterns\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],"django patterns","django","patterns","view","when","scoped","apps","layout","permission","implementation","backend","use","writing","write","read","model","core","rbac","modular","test","2026-11-10 10:12:30",false,"---\nname: django-patterns\ndescription: Django 5.2 + DRF implementation patterns specific to Aprender Sistema v2 (modular apps\u002Fcore layout, HasPerm RBAC, read\u002Fwrite serializers, service layer, owner-scoped querysets). Use when writing a model, serializer, view\u002Fviewset, service, permission, or test in the v2 backend.\n---\n\n# Django\u002FDRF Patterns — Aprender Sistema v2\n\nImplementation patterns for the v2 backend. This file holds the AS-v2-specific deltas;\nthe full copy-paste scaffolds live in `reference\u002F` (see pointers below). For anything\ngeneric to Django\u002FDRF, follow the framework defaults — this skill only documents where\nAS v2 diverges.\n\n## Backend layout (modular)\n\nThe only real apps are `apps\u002Fcore` (39 models, `serializers\u002F`, `services\u002F`) and\n`apps\u002Fdev_tools` (15 seed commands, disabled in prod). `apps\u002Fcore` is split into Python\npackages, each with an `__init__.py` that re-exports its public names:\n\n```\napps\u002Fcore\u002F\n├── models\u002F        # by domain; __init__.py re-exports all models\n├── serializers\u002F   # by domain; __init__.py re-exports\n├── views\u002F         # compat re-export wrappers (e.g. views\u002Fsolicitacao.py)\n├── views_*.py     # canonical view modules (views_solicitacao.py, views_availability.py, …)\n├── views_gcal\u002F    # GCal views\n├── rbac\u002F          # RBAC SSOT (HasPerm, helpers, matrix, policies)\n└── services\u002F      # business logic (availability_service.py, gcal\u002F, …)\n```\n\n**Re-export discipline**: when you add a model\u002Fserializer, re-export it in the package's\n`__init__.py` so existing imports keep working. Note `apps\u002Fcore\u002Fviews\u002Fsolicitacao.py` is a\nthin compat wrapper — the canonical ViewSet lives in `apps\u002Fcore\u002Fviews_solicitacao.py`.\n\n## Quick reference\n\n| Task | Pattern | Pointer |\n|------|---------|---------|\n| Model | SSOT + constraints + indexes + re-export | `reference\u002Fmodel-template.md` |\n| Serializer (read) | `StringRelatedField`, formatted fields | `reference\u002Fserializer-template.md` |\n| Serializer (write) | `PrimaryKeyRelatedField` + validation | `reference\u002Fserializer-template.md` |\n| ViewSet | thin controller, logic in services | `reference\u002Fviewset-template.md` |\n| Permission | `HasPerm(\"codename\")` | RBAC section below |\n| Owner\u002Fsector scope | filter in `get_queryset()` | RBAC section below |\n| Test | nested classes per requirement, behavior asserts | `reference\u002Ftest-template.md` |\n| Query perf | `select_related` \u002F `prefetch_related` | Performance section below |\n\n---\n\n## Models\n\nFull scaffold: **`reference\u002Fmodel-template.md`**.\n\nAS-v2 deltas to keep in mind:\n- **Timezone**: `DateTimeField` stores UTC; display converts to `America\u002FFortaleza`.\n- **Constraints in the DB**: prefer `CheckConstraint`\u002F`UniqueConstraint` in `Meta`; reach\n  for Python validators only when the rule needs relations or runtime data.\n- **`save()` deriving fields**: real pattern in `apps\u002Fcore\u002Fmodels\u002Fdat_registro.py` — `save()`\n  calls `_calcular_nr_codigos()` to compute `nr_codigos` from `projeto_geral`.\n- **Default masks required**: a model field with `default=` makes `ModelSerializer` accept a\n  payload that omits it. When the field must be supplied, declare it as\n  `ChoiceField(required=True)` on the write serializer (case `Projeto.fluxo`, #1312).\n\n---\n\n## Serializers (DRF)\n\nFull scaffold + gotchas: **`reference\u002Fserializer-template.md`**.\n\nRead\u002Fwrite split is the house style: read serializers are user-friendly\n(`StringRelatedField`, formatted fields, nested), write serializers take IDs\n(`PrimaryKeyRelatedField`) and validate. Pick per request in the ViewSet's\n`get_serializer_class()`.\n\n---\n\n## Views \u002F ViewSets\n\nFull scaffold: **`reference\u002Fviewset-template.md`**.\n\nAS-v2 deltas:\n- **Thin controllers**: views validate + delegate to `apps\u002Fcore\u002Fservices\u002F`; keep business\n  logic out of the view body.\n- **`get_serializer_class()`** switches read vs write by `self.action`.\n- **Owner\u002Fsector scope** is filtered in `get_queryset()` (see RBAC below), not re-checked in\n  the body.\n- **`get_permissions()` override hides `@action(permission_classes=...)`** — if a ViewSet\n  overrides `get_permissions()`, the action decorator's classes are ignored. Check it before\n  assuming an action's permissions. (`SolicitacaoViewSet` does this, mapping `approve`\u002F\n  `batch_approve` to the Policy `CanAccessSolicitationApprovals`.)\n\n---\n\n## Permissions (RBAC)\n\nThe AS v2 RBAC is **capability-based**. SSOT is `apps.core.rbac` (DRF permissions, helpers,\ndata-scope constants, matrix, policies). **NEVER** use `user.groups.filter(name=...)` in\nviews\u002Fpermissions — it is banned by `scripts\u002Frbac_lint.py` (CI job `[required] backend\nrbac-lint`). `apps\u002Fcore\u002Fpermissions.py` is a compat shim — import from `apps.core.rbac`.\n\nCanonical idiom — capability codenames are English (`approve_solicitation`,\n`create_solicitation`, `import_spreadsheet`, `operate_preagenda`, …):\n\n```python\nfrom apps.core.rbac import HasPerm\n\npermission_classes = [HasPerm(\"create_solicitation\")]                 # single capability\npermission_classes = [HasPerm(\"operate_preagenda\") | HasPerm(\"create_solicitation\")]  # OR\npermission_classes = [IsAuthenticated, HasPerm(\"import_spreadsheet\")]  # AND\npermission_classes = [~HasPerm(\"bloqueado\")]                          # NOT\n```\n\nAprovar **não** se gateia por `HasPerm(\"approve_solicitation\")`: a decisão é a Policy\n`CanAccessSolicitationApprovals` (regra única `solicitation_approval_basis`, 3 bases:\nsuperuser, GERENTE vigente na gerência Superintendência, ou a capacidade de aprovar vinda do\npacote do perfil da gerência — DAT\u002FControle). A base do GERENTE não é capacidade, então\n`HasPerm` a negaria. Ver `reference\u002Fviewset-template.md`.\n\n`HasPerm(\"a\") | HasPerm(\"b\")` composition is tactical (ok for ≤2 capabilities). For ≥3 caps,\na shared rule, or \"who can see this and why\" repeated across sites, promote it to a **Policy\nclass** in `apps\u002Fcore\u002Frbac\u002Fpolicies.py` (e.g. `CanAccessSolicitationApprovals`,\n`CanUseGcal`).\n\nProgrammatic checks outside views (services, signals, commands):\n\n```python\nfrom apps.core.rbac import user_has_any_perm, user_has_all_perms\n\nif user_has_any_perm(user, \"operate_preagenda\", \"create_solicitation\"):\n    ...\n```\n\n**Data-scope \u002F object-level**: filter in `get_queryset()` + capabilities — don't reimplement\nidentity checks by group.\n\n```python\nfrom apps.core.services.solicitacao_scope import scope_solicitacoes\n\ndef get_queryset(self):\n    base = Solicitacao.objects.select_related(\"usuario\")  # dono = `usuario`\n    # escopo SSOT: global (superuser\u002Fcapacidades) + gestora (GERENTE vigente) + APOIO + próprias\n    return scope_solicitacoes(base, self.request.user)\n```\n\nFull naming convention: `v2\u002Fdocs\u002FRBAC_NAMING.md` + `v2\u002Fdocs\u002Fspecs\u002Fbackend\u002Frbac.spec.md`.\n\n---\n\n## Testing\n\nFull scaffold + conventions: **`reference\u002Ftest-template.md`**.\n\nAS-v2 deltas:\n- **Nested classes per requirement** (`TestSolicitacaoApproval` → `TestManualApproval` for\n  PA-01, `TestPermissions` for PA-02); docstrings name the rule.\n- **Test behavior, not implementation** — assert status code \u002F persisted state \u002F audit log,\n  never that a method was called.\n- **RBAC asserts the 403 status**, not `\"Setor\" in response.data` (that ties the test to the\n  legacy org chart).\n- **Determinism**: atomic counter for unique CPF\u002Femail (not `abs(hash(str)) % N`); never\n  hardcode a date whose assertion depends on a not-yet-reached deadline.\n- **Pyright header**: a new test file needs the same `# pyright: ...=false` header its\n  neighbors carry, or CI breaks.\n\nReal suites in `apps\u002Fcore\u002Ftests\u002F`: `test_solicitacao_fluxo.py`,\n`test_solicitacao_approval_concurrency.py`, `test_views_solicitacao_coverage.py`,\n`test_solicitacao_serializer_meet_link.py`.\n\n---\n\n## Performance\n\nQuick rule: `select_related` (FK\u002FOneToOne) + `prefetch_related` (M2M\u002Freverse FK) to kill N+1.\nEndpoint-level caching exists (e.g. `availability_check:` keys at `timeout=300` via the\n`cache_availability_check` decorator; the monthly availability grid caches in\n`views_availability_monthly.py` with a TTL+jitter). For slow endpoints, deep N+1, bundle, or\nCore Web Vitals, **use the `performance-optimization` skill** (perf SSOT) — don't duplicate\nguidance here.\n\n```python\nsolicitacoes = Solicitacao.objects.select_related(\"usuario\")  # avoids N+1\n```\n\n---\n\n## Real implementations to copy from\n\n- **CRUD**: models `apps\u002Fcore\u002Fmodels\u002Fsolicitacao.py`, `usuario.py`, `organizacao.py`;\n  serializers `serializers\u002Fsolicitacao.py`, `serializers\u002Fusuario.py`; view\n  `views_solicitacao.py`; permissions `apps\u002Fcore\u002Frbac`.\n- **DAT module** (4-step workflow Carta → Contato → Reunião → Entrega): models\n  `models\u002Fdat_acao.py`, `dat_cadastro.py`, `dat_registro.py` (`save()` auto-derives\n  `nr_codigos`).\n- **PlanoFormacoes**: models `models\u002Fplano_formacoes.py`, `formacao.py`, `acompanhamento.py`,\n  `prova.py`; `recalcular_ch()` + `taxa_realizacao` property.\n- **Service layer**: `services\u002Favailability_service.py` (RD-01..RD-08),\n  `services\u002Fgcal\u002Fsync.py` + `gcal\u002Fpayload.py` (RF05\u002FRF06),\n  `services\u002Fsolicitacao_approval.py` (PA-01..PA-07).\n- **Import**: command `import_export_contract` + `services\u002Fexport_contract_importer.py`\n  (dry-run by default).\n\n## Related\n\n- **Business rules**: `aprender-domain` skill (CP, RD, PA, RF, DAT, PlanoFormacoes)\n- **RBAC**: `v2\u002Fdocs\u002FRBAC_NAMING.md` + `v2\u002Fdocs\u002Fspecs\u002Fbackend\u002Frbac.spec.md`\n- **Performance**: `performance-optimization` skill\n- **Imports**: `v2\u002Fdocs\u002Fspecs\u002Fbackend\u002Fimports.spec.md` (legacy ETL removed — use\n  `import_export_contract` + DRF endpoints)\n","# Django\u002FDRF Patterns — Aprender Sistema v2\n\nImplementation patterns for the v2 backend. This file holds the AS-v2-specific deltas;\nthe full copy-paste scaffolds live in `reference\u002F` (see pointers below). For anything\ngeneric to Django\u002FDRF, follow the framework defaults — this skill only documents where\nAS v2 diverges.\n\n## Backend layout (modular)\n\nThe only real apps are `apps\u002Fcore` (39 models, `serializers\u002F`, `services\u002F`) and\n`apps\u002Fdev_tools` (15 seed commands, disabled in prod). `apps\u002Fcore` is split into Python\npackages, each with an `__init__.py` that re-exports its public names:\n\n```\napps\u002Fcore\u002F\n├── models\u002F        # by domain; __init__.py re-exports all models\n├── serializers\u002F   # by domain; __init__.py re-exports\n├── views\u002F         # compat re-export wrappers (e.g. views\u002Fsolicitacao.py)\n├── views_*.py     # canonical view modules (views_solicitacao.py, views_availability.py, …)\n├── views_gcal\u002F    # GCal views\n├── rbac\u002F          # RBAC SSOT (HasPerm, helpers, matrix, policies)\n└── services\u002F      # business logic (availability_service.py, gcal\u002F, …)\n```\n\n**Re-export discipline**: when you add a model\u002Fserializer, re-export it in the package's\n`__init__.py` so existing imports keep working. Note `apps\u002Fcore\u002Fviews\u002Fsolicitacao.py` is a\nthin compat wrapper — the canonical ViewSet lives in `apps\u002Fcore\u002Fviews_solicitacao.py`.\n\n## Quick reference\n\n| Task | Pattern | Pointer |\n|------|---------|---------|\n| Model | SSOT + constraints + indexes + re-export | `reference\u002Fmodel-template.md` |\n| Serializer (read) | `StringRelatedField`, formatted fields | `reference\u002Fserializer-template.md` |\n| Serializer (write) | `PrimaryKeyRelatedField` + validation | `reference\u002Fserializer-template.md` |\n| ViewSet | thin controller, logic in services | `reference\u002Fviewset-template.md` |\n| Permission | `HasPerm(\"codename\")` | RBAC section below |\n| Owner\u002Fsector scope | filter in `get_queryset()` | RBAC section below |\n| Test | nested classes per requirement, behavior asserts | `reference\u002Ftest-template.md` |\n| Query perf | `select_related` \u002F `prefetch_related` | Performance section below |\n\n---\n\n## Models\n\nFull scaffold: **`reference\u002Fmodel-template.md`**.\n\nAS-v2 deltas to keep in mind:\n- **Timezone**: `DateTimeField` stores UTC; display converts to `America\u002FFortaleza`.\n- **Constraints in the DB**: prefer `CheckConstraint`\u002F`UniqueConstraint` in `Meta`; reach\n  for Python validators only when the rule needs relations or runtime data.\n- **`save()` deriving fields**: real pattern in `apps\u002Fcore\u002Fmodels\u002Fdat_registro.py` — `save()`\n  calls `_calcular_nr_codigos()` to compute `nr_codigos` from `projeto_geral`.\n- **Default masks required**: a model field with `default=` makes `ModelSerializer` accept a\n  payload that omits it. When the field must be supplied, declare it as\n  `ChoiceField(required=True)` on the write serializer (case `Projeto.fluxo`, #1312).\n\n---\n\n## Serializers (DRF)\n\nFull scaffold + gotchas: **`reference\u002Fserializer-template.md`**.\n\nRead\u002Fwrite split is the house style: read serializers are user-friendly\n(`StringRelatedField`, formatted fields, nested), write serializers take IDs\n(`PrimaryKeyRelatedField`) and validate. Pick per request in the ViewSet's\n`get_serializer_class()`.\n\n---\n\n## Views \u002F ViewSets\n\nFull scaffold: **`reference\u002Fviewset-template.md`**.\n\nAS-v2 deltas:\n- **Thin controllers**: views validate + delegate to `apps\u002Fcore\u002Fservices\u002F`; keep business\n  logic out of the view body.\n- **`get_serializer_class()`** switches read vs write by `self.action`.\n- **Owner\u002Fsector scope** is filtered in `get_queryset()` (see RBAC below), not re-checked in\n  the body.\n- **`get_permissions()` override hides `@action(permission_classes=...)`** — if a ViewSet\n  overrides `get_permissions()`, the action decorator's classes are ignored. Check it before\n  assuming an action's permissions. (`SolicitacaoViewSet` does this, mapping `approve`\u002F\n  `batch_approve` to the Policy `CanAccessSolicitationApprovals`.)\n\n---\n\n## Permissions (RBAC)\n\nThe AS v2 RBAC is **capability-based**. SSOT is `apps.core.rbac` (DRF permissions, helpers,\ndata-scope constants, matrix, policies). **NEVER** use `user.groups.filter(name=...)` in\nviews\u002Fpermissions — it is banned by `scripts\u002Frbac_lint.py` (CI job `[required] backend\nrbac-lint`). `apps\u002Fcore\u002Fpermissions.py` is a compat shim — import from `apps.core.rbac`.\n\nCanonical idiom — capability codenames are English (`approve_solicitation`,\n`create_solicitation`, `import_spreadsheet`, `operate_preagenda`, …):\n\n```python\nfrom apps.core.rbac import HasPerm\n\npermission_classes = [HasPerm(\"create_solicitation\")]                 # single capability\npermission_classes = [HasPerm(\"operate_preagenda\") | HasPerm(\"create_solicitation\")]  # OR\npermission_classes = [IsAuthenticated, HasPerm(\"import_spreadsheet\")]  # AND\npermission_classes = [~HasPerm(\"bloqueado\")]                          # NOT\n```\n\nAprovar **não** se gateia por `HasPerm(\"approve_solicitation\")`: a decisão é a Policy\n`CanAccessSolicitationApprovals` (regra única `solicitation_approval_basis`, 3 bases:\nsuperuser, GERENTE vigente na gerência Superintendência, ou a capacidade de aprovar vinda do\npacote do perfil da gerência — DAT\u002FControle). A base do GERENTE não é capacidade, então\n`HasPerm` a negaria. Ver `reference\u002Fviewset-template.md`.\n\n`HasPerm(\"a\") | HasPerm(\"b\")` composition is tactical (ok for ≤2 capabilities). For ≥3 caps,\na shared rule, or \"who can see this and why\" repeated across sites, promote it to a **Policy\nclass** in `apps\u002Fcore\u002Frbac\u002Fpolicies.py` (e.g. `CanAccessSolicitationApprovals`,\n`CanUseGcal`).\n\nProgrammatic checks outside views (services, signals, commands):\n\n```python\nfrom apps.core.rbac import user_has_any_perm, user_has_all_perms\n\nif user_has_any_perm(user, \"operate_preagenda\", \"create_solicitation\"):\n    ...\n```\n\n**Data-scope \u002F object-level**: filter in `get_queryset()` + capabilities — don't reimplement\nidentity checks by group.\n\n```python\nfrom apps.core.services.solicitacao_scope import scope_solicitacoes\n\ndef get_queryset(self):\n    base = Solicitacao.objects.select_related(\"usuario\")  # dono = `usuario`\n    # escopo SSOT: global (superuser\u002Fcapacidades) + gestora (GERENTE vigente) + APOIO + próprias\n    return scope_solicitacoes(base, self.request.user)\n```\n\nFull naming convention: `v2\u002Fdocs\u002FRBAC_NAMING.md` + `v2\u002Fdocs\u002Fspecs\u002Fbackend\u002Frbac.spec.md`.\n\n---\n\n## Testing\n\nFull scaffold + conventions: **`reference\u002Ftest-template.md`**.\n\nAS-v2 deltas:\n- **Nested classes per requirement** (`TestSolicitacaoApproval` → `TestManualApproval` for\n  PA-01, `TestPermissions` for PA-02); docstrings name the rule.\n- **Test behavior, not implementation** — assert status code \u002F persisted state \u002F audit log,\n  never that a method was called.\n- **RBAC asserts the 403 status**, not `\"Setor\" in response.data` (that ties the test to the\n  legacy org chart).\n- **Determinism**: atomic counter for unique CPF\u002Femail (not `abs(hash(str)) % N`); never\n  hardcode a date whose assertion depends on a not-yet-reached deadline.\n- **Pyright header**: a new test file needs the same `# pyright: ...=false` header its\n  neighbors carry, or CI breaks.\n\nReal suites in `apps\u002Fcore\u002Ftests\u002F`: `test_solicitacao_fluxo.py`,\n`test_solicitacao_approval_concurrency.py`, `test_views_solicitacao_coverage.py`,\n`test_solicitacao_serializer_meet_link.py`.\n\n---\n\n## Performance\n\nQuick rule: `select_related` (FK\u002FOneToOne) + `prefetch_related` (M2M\u002Freverse FK) to kill N+1.\nEndpoint-level caching exists (e.g. `availability_check:` keys at `timeout=300` via the\n`cache_availability_check` decorator; the monthly availability grid caches in\n`views_availability_monthly.py` with a TTL+jitter). For slow endpoints, deep N+1, bundle, or\nCore Web Vitals, **use the `performance-optimization` skill** (perf SSOT) — don't duplicate\nguidance here.\n\n```python\nsolicitacoes = Solicitacao.objects.select_related(\"usuario\")  # avoids N+1\n```\n\n---\n\n## Real implementations to copy from\n\n- **CRUD**: models `apps\u002Fcore\u002Fmodels\u002Fsolicitacao.py`, `usuario.py`, `organizacao.py`;\n  serializers `serializers\u002Fsolicitacao.py`, `serializers\u002Fusuario.py`; view\n  `views_solicitacao.py`; permissions `apps\u002Fcore\u002Frbac`.\n- **DAT module** (4-step workflow Carta → Contato → Reunião → Entrega): models\n  `models\u002Fdat_acao.py`, `dat_cadastro.py`, `dat_registro.py` (`save()` auto-derives\n  `nr_codigos`).\n- **PlanoFormacoes**: models `models\u002Fplano_formacoes.py`, `formacao.py`, `acompanhamento.py`,\n  `prova.py`; `recalcular_ch()` + `taxa_realizacao` property.\n- **Service layer**: `services\u002Favailability_service.py` (RD-01..RD-08),\n  `services\u002Fgcal\u002Fsync.py` + `gcal\u002Fpayload.py` (RF05\u002FRF06),\n  `services\u002Fsolicitacao_approval.py` (PA-01..PA-07).\n- **Import**: command `import_export_contract` + `services\u002Fexport_contract_importer.py`\n  (dry-run by default).\n\n## Related\n\n- **Business rules**: `aprender-domain` skill (CP, RD, PA, RF, DAT, PlanoFormacoes)\n- **RBAC**: `v2\u002Fdocs\u002FRBAC_NAMING.md` + `v2\u002Fdocs\u002Fspecs\u002Fbackend\u002Frbac.spec.md`\n- **Performance**: `performance-optimization` skill\n- **Imports**: `v2\u002Fdocs\u002Fspecs\u002Fbackend\u002Fimports.spec.md` (legacy ETL removed — use\n  `import_export_contract` + DRF endpoints)\n",{"name":5,"description":7},"main","9e3a882d83e0853bdc570ae9d89c02d2a53bed82",".claude\u002Fskills\u002Fdjango-patterns","https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa\u002Faprender_sistema","https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa","Dev Python | IA | Automation | HTML | CSS | Data | Process | Projects","2026-11-11 08:34:26",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add matheusnorjosa\u002Faprender_sistema --skill django-patterns",{"tool":65,"command":66},"bunx","bunx skills add matheusnorjosa\u002Faprender_sistema --skill django-patterns",{"tool":68,"command":69},"pnpm","pnpm dlx skills add matheusnorjosa\u002Faprender_sistema --skill django-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa\u002Faprender_sistema\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fdjango-patterns\u002FSKILL.md",true,[73,79,83,87],{"path":74,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":77,"sourceHtmlUrl":78},"reference\u002Fmodel-template.md","REFERENCE","参考文档",3672,"https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa\u002Faprender_sistema\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fdjango-patterns\u002Freference\u002Fmodel-template.md",{"path":80,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":81,"sourceHtmlUrl":82},"reference\u002Fserializer-template.md",4163,"https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa\u002Faprender_sistema\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fdjango-patterns\u002Freference\u002Fserializer-template.md",{"path":84,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":85,"sourceHtmlUrl":86},"reference\u002Ftest-template.md",4666,"https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa\u002Faprender_sistema\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fdjango-patterns\u002Freference\u002Ftest-template.md",{"path":88,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":89,"sourceHtmlUrl":90},"reference\u002Fviewset-template.md",4055,"https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa\u002Faprender_sistema\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fdjango-patterns\u002Freference\u002Fviewset-template.md",[92,126,149,166,178,210],{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":106,"publishedAt":47},"01M6C0WHSP7S2QMJGGMQRXJ6PD","writing-standards","Apply AS v2 technical-writing standards (clarity, brevity, active voice, Python\u002FDjango conventions). Use when writing a README, a docstring (PEP 257), a commit message, a PR description, an error message, or any technical doc.","https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa\u002Faprender_sistema\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fwriting-standards\u002FSKILL.md",[98,101],{"categoryNo":99,"categoryName":100,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":102,"categoryName":103,"taxonomyType":104,"taxonomyTypeDesc":105},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[39,107,108,109,110,111,112,113,114,115,116,28,117,118,119,120,121,122,123,124,125,31],"writing standards","standards","python","commit","pr","pr description","commit message","doc","voice","clarity","technical","README","message","active","as","error","technical-writing","brevity","docstring",{"skillNo":127,"name":128,"nameZh":6,"description":129,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":130,"categories":131,"keywords":132,"publishedAt":47},"01M6C0WG2SBP9PJG1YQFGGVJAR","verification-gate","Verify before claiming success. Use when about to say something works\u002Fis done, after implementing a feature, after a bugfix, or before pushing — run the proof command and confirm output first.","https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa\u002Faprender_sistema\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fverification-gate\u002FSKILL.md",[],[133,134,135,136,137,138,139,38,140,141,142,143,144,145,146,147,148,31],"verification","verification gate","gate","run","first","verify","command","verify before claiming","say","done","feature","proof","bugfix","output","about","implementing",{"skillNo":150,"name":151,"nameZh":6,"description":152,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":153,"categories":154,"keywords":156,"publishedAt":47},"01M6C0WE010G12KH45YZW6M7K5","test-driven-development","Write the failing test before the implementation in AS v2 (pytest + Django\u002FDRF). Use when implementing a feature or fixing a bug, before any production code is written.","https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa\u002Faprender_sistema\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ftest-driven-development\u002FSKILL.md",[155],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[46,157,158,159,160,161,28,40,38,162,36,163,143,121,164,148,31,165],"test driven development","development","driven","code","Production","bug","pytest","drf","failing",{"skillNo":167,"name":168,"nameZh":6,"description":169,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":170,"categories":171,"keywords":172,"publishedAt":47},"01M6C0WC6Y81XRVBJQSTKA96XQ","subagent-development","Orquestra subagents no AS v2 — decompõe a tarefa em domínios independentes, paraleliza e revisa em 2 estágios. Use ao delegar exploração, implementação ou validação cross-arquivo para acelerar o trabalho e poupar o contexto principal.","https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa\u002Faprender_sistema\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fsubagent-development\u002FSKILL.md",[],[158,173,174,175,176,38,177,121],"subagent","subagent development","para","subagents","ao",{"skillNo":179,"name":180,"nameZh":6,"description":181,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":182,"categories":183,"keywords":184,"publishedAt":47},"01M6C0W9W8D6JJWXW28Q7ZHAC9","security-scan","Automated security scanning for AS v2. Use before commits or when reviewing changes for vulnerabilities. Runs dependency audit (pip-audit, npm audit), secret detection (grep patterns), and code pattern scanning (SQL injection, XSS, eval, pickle, hardcoded secrets). Integrates with project hooks system.","https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa\u002Faprender_sistema\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fsecurity-scan\u002FSKILL.md",[],[185,186,187,188,189,160,190,191,192,193,194,195,196,197,198,199,200,201,38,202,203,204,121,205,206,207,208,209,31],"security","security scan","scan","vulnerabilities","sql","npm","audit","dependency audit","detection","injection","xss","secrets","pip-audit","commits","system","grep","eval","hooks","security scanning","project","with","true","pip","for","changes",{"skillNo":211,"name":212,"nameZh":6,"description":213,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":214,"categories":215,"keywords":219,"publishedAt":47},"01M6C0W7RE3G3C2852YXQKR5J9","resume-handoff","Resume work from a saved handoff document, validating its state against the current codebase before continuing. Use when resuming work from a saved handoff after a context clear or in a new session (path, session name, or GitHub issue).","https:\u002F\u002Fgithub.com\u002Fmatheusnorjosa\u002Faprender_sistema\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fresume-handoff\u002FSKILL.md",[216],{"categoryNo":217,"categoryName":218,"taxonomyType":104,"taxonomyTypeDesc":105},"01JBSEEDCAT000000000000038","人力资源",[220,221,222,223,224,225,226,227,228,38,229,230,231,232,233,234,235,236,31,237],"handoff","resume handoff","resume","github","state","new session","work","context","session","github issue","issue","document","clear","name","saved","codebase","resuming","new"]