@geraldmaron/construct 1.0.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.
- package/.env.example +69 -0
- package/LICENSE +21 -0
- package/README.md +344 -0
- package/agents/prompts/cx-accessibility.md +29 -0
- package/agents/prompts/cx-ai-engineer.md +31 -0
- package/agents/prompts/cx-architect.md +40 -0
- package/agents/prompts/cx-business-strategist.md +25 -0
- package/agents/prompts/cx-data-analyst.md +30 -0
- package/agents/prompts/cx-data-engineer.md +32 -0
- package/agents/prompts/cx-debugger.md +27 -0
- package/agents/prompts/cx-designer.md +33 -0
- package/agents/prompts/cx-devil-advocate.md +36 -0
- package/agents/prompts/cx-docs-keeper.md +50 -0
- package/agents/prompts/cx-engineer.md +36 -0
- package/agents/prompts/cx-evaluator.md +26 -0
- package/agents/prompts/cx-explorer.md +38 -0
- package/agents/prompts/cx-legal-compliance.md +25 -0
- package/agents/prompts/cx-operations.md +28 -0
- package/agents/prompts/cx-orchestrator.md +30 -0
- package/agents/prompts/cx-platform-engineer.md +25 -0
- package/agents/prompts/cx-product-manager.md +30 -0
- package/agents/prompts/cx-qa.md +42 -0
- package/agents/prompts/cx-rd-lead.md +25 -0
- package/agents/prompts/cx-release-manager.md +31 -0
- package/agents/prompts/cx-researcher.md +31 -0
- package/agents/prompts/cx-reviewer.md +36 -0
- package/agents/prompts/cx-security.md +37 -0
- package/agents/prompts/cx-sre.md +26 -0
- package/agents/prompts/cx-test-automation.md +35 -0
- package/agents/prompts/cx-trace-reviewer.md +76 -0
- package/agents/prompts/cx-ux-researcher.md +30 -0
- package/agents/registry.json +879 -0
- package/agents/teams.json +94 -0
- package/bin/construct +613 -0
- package/commands/build/feature.md +21 -0
- package/commands/build/fix.md +20 -0
- package/commands/design/access.md +19 -0
- package/commands/design/flow.md +16 -0
- package/commands/design/ui.md +18 -0
- package/commands/measure/experiment.md +18 -0
- package/commands/measure/metrics.md +18 -0
- package/commands/measure/results.md +18 -0
- package/commands/plan/api.md +19 -0
- package/commands/plan/challenge.md +18 -0
- package/commands/plan/decide.md +20 -0
- package/commands/plan/feature.md +49 -0
- package/commands/plan/requirements.md +24 -0
- package/commands/remember/context.md +26 -0
- package/commands/remember/handoff.md +19 -0
- package/commands/remember/runbook.md +20 -0
- package/commands/review/code.md +21 -0
- package/commands/review/quality.md +19 -0
- package/commands/review/security.md +16 -0
- package/commands/ship/ready.md +19 -0
- package/commands/ship/release.md +19 -0
- package/commands/ship/status.md +18 -0
- package/commands/understand/docs.md +22 -0
- package/commands/understand/research.md +22 -0
- package/commands/understand/this.md +23 -0
- package/commands/understand/why.md +18 -0
- package/commands/work/clean.md +32 -0
- package/commands/work/drive.md +69 -0
- package/commands/work/optimize-prompts.md +46 -0
- package/commands/work/parallel-review.md +40 -0
- package/db/migrations/001_init.sql +38 -0
- package/langfuse/docker-compose.yml +82 -0
- package/lib/audit-skills.mjs +118 -0
- package/lib/auto-docs.mjs +293 -0
- package/lib/cli-commands.mjs +409 -0
- package/lib/codex-config.mjs +114 -0
- package/lib/comment-lint.mjs +191 -0
- package/lib/completions.mjs +170 -0
- package/lib/context-state.mjs +99 -0
- package/lib/cost.mjs +213 -0
- package/lib/distill.mjs +403 -0
- package/lib/efficiency.mjs +139 -0
- package/lib/env-config.mjs +53 -0
- package/lib/eval-harness.mjs +59 -0
- package/lib/features.mjs +209 -0
- package/lib/headhunt.mjs +597 -0
- package/lib/hooks/adaptive-lint.mjs +112 -0
- package/lib/hooks/agent-tracker.mjs +50 -0
- package/lib/hooks/bootstrap-guard.mjs +90 -0
- package/lib/hooks/comment-lint.mjs +26 -0
- package/lib/hooks/config-protection.mjs +52 -0
- package/lib/hooks/console-warn.mjs +43 -0
- package/lib/hooks/context-window-recovery.mjs +90 -0
- package/lib/hooks/continuation-enforcer.mjs +72 -0
- package/lib/hooks/dep-audit.mjs +155 -0
- package/lib/hooks/drive-guard.mjs +89 -0
- package/lib/hooks/edit-accumulator.mjs +36 -0
- package/lib/hooks/edit-error-recovery.mjs +46 -0
- package/lib/hooks/edit-guard.mjs +109 -0
- package/lib/hooks/env-check.mjs +80 -0
- package/lib/hooks/guard-bash.mjs +83 -0
- package/lib/hooks/mcp-audit.mjs +57 -0
- package/lib/hooks/mcp-health-check.mjs +51 -0
- package/lib/hooks/mcp-task-scope.mjs +47 -0
- package/lib/hooks/model-fallback.mjs +105 -0
- package/lib/hooks/pre-compact.mjs +212 -0
- package/lib/hooks/pre-push-gate.mjs +129 -0
- package/lib/hooks/read-tracker.mjs +129 -0
- package/lib/hooks/registry-sync.mjs +23 -0
- package/lib/hooks/scan-secrets.mjs +76 -0
- package/lib/hooks/session-start.mjs +95 -0
- package/lib/hooks/stop-notify.mjs +191 -0
- package/lib/hooks/stop-typecheck.mjs +83 -0
- package/lib/hooks/task-completed-guard.mjs +43 -0
- package/lib/hooks/teammate-idle-guard.mjs +54 -0
- package/lib/hooks/workflow-guard.mjs +62 -0
- package/lib/host-capabilities.mjs +123 -0
- package/lib/init-docs.mjs +382 -0
- package/lib/mcp/server.mjs +1123 -0
- package/lib/mcp-catalog.json +243 -0
- package/lib/mcp-manager.mjs +433 -0
- package/lib/mcp-platform-config.mjs +104 -0
- package/lib/model-router.mjs +810 -0
- package/lib/opencode-config.mjs +44 -0
- package/lib/opencode-runtime-plugin.mjs +909 -0
- package/lib/opencode-telemetry.mjs +433 -0
- package/lib/orchestration-policy.mjs +258 -0
- package/lib/prompt-composer.mjs +196 -0
- package/lib/prompt-metadata.mjs +68 -0
- package/lib/review.mjs +429 -0
- package/lib/role-preload.mjs +52 -0
- package/lib/schemas/decision.json +50 -0
- package/lib/schemas/implementation.json +51 -0
- package/lib/schemas/review-report.json +32 -0
- package/lib/schemas/test-report.json +43 -0
- package/lib/server/index.mjs +334 -0
- package/lib/server/static/app.js +841 -0
- package/lib/server/static/index.html +820 -0
- package/lib/service-manager.mjs +225 -0
- package/lib/setup.mjs +319 -0
- package/lib/status.mjs +707 -0
- package/lib/storage/backend.mjs +44 -0
- package/lib/storage/embeddings.mjs +70 -0
- package/lib/storage/hybrid-query.mjs +184 -0
- package/lib/storage/sql-store.mjs +55 -0
- package/lib/storage/state-source.mjs +101 -0
- package/lib/storage/sync.mjs +164 -0
- package/lib/storage/vector-store.mjs +59 -0
- package/lib/telemetry/backends/langfuse.mjs +58 -0
- package/lib/telemetry/backends/noop.mjs +16 -0
- package/lib/telemetry/langfuse-ingest.mjs +108 -0
- package/lib/telemetry/langfuse-model-sync.mjs +270 -0
- package/lib/telemetry/team-rollup.mjs +143 -0
- package/lib/toolkit-env.mjs +30 -0
- package/lib/validator.mjs +181 -0
- package/lib/workflow-state.mjs +794 -0
- package/package.json +53 -0
- package/personas/construct.md +94 -0
- package/platforms/claude/CLAUDE.md +30 -0
- package/platforms/claude/settings.template.json +472 -0
- package/platforms/opencode/config.template.json +65 -0
- package/platforms/opencode/plugins/construct-fallback.js +5 -0
- package/platforms/opencode/sync-config.mjs +69 -0
- package/rules/common/agents.md +55 -0
- package/rules/common/code-review.md +129 -0
- package/rules/common/coding-style.md +95 -0
- package/rules/common/comments.md +139 -0
- package/rules/common/cx-agent-routing.md +61 -0
- package/rules/common/cx-skill-routing.md +11 -0
- package/rules/common/development-workflow.md +49 -0
- package/rules/common/git-workflow.md +29 -0
- package/rules/common/hooks.md +35 -0
- package/rules/common/patterns.md +36 -0
- package/rules/common/performance.md +71 -0
- package/rules/common/security.md +34 -0
- package/rules/common/testing.md +62 -0
- package/rules/golang/coding-style.md +37 -0
- package/rules/golang/hooks.md +22 -0
- package/rules/golang/patterns.md +50 -0
- package/rules/golang/security.md +39 -0
- package/rules/golang/testing.md +36 -0
- package/rules/python/coding-style.md +47 -0
- package/rules/python/hooks.md +24 -0
- package/rules/python/patterns.md +44 -0
- package/rules/python/security.md +35 -0
- package/rules/python/testing.md +43 -0
- package/rules/swift/coding-style.md +52 -0
- package/rules/swift/hooks.md +25 -0
- package/rules/swift/patterns.md +71 -0
- package/rules/swift/security.md +38 -0
- package/rules/swift/testing.md +50 -0
- package/rules/typescript/coding-style.md +204 -0
- package/rules/typescript/hooks.md +27 -0
- package/rules/typescript/patterns.md +57 -0
- package/rules/typescript/security.md +33 -0
- package/rules/typescript/testing.md +23 -0
- package/rules/web/coding-style.md +101 -0
- package/rules/web/design-quality.md +68 -0
- package/rules/web/hooks.md +125 -0
- package/rules/web/patterns.md +84 -0
- package/rules/web/performance.md +69 -0
- package/rules/web/security.md +62 -0
- package/rules/web/testing.md +60 -0
- package/rules/zh/README.md +113 -0
- package/rules/zh/agents.md +55 -0
- package/rules/zh/code-review.md +129 -0
- package/rules/zh/coding-style.md +53 -0
- package/rules/zh/development-workflow.md +49 -0
- package/rules/zh/git-workflow.md +29 -0
- package/rules/zh/hooks.md +35 -0
- package/rules/zh/patterns.md +36 -0
- package/rules/zh/performance.md +60 -0
- package/rules/zh/security.md +34 -0
- package/rules/zh/testing.md +34 -0
- package/skills/ai/agent-dev.md +102 -0
- package/skills/ai/llm-security.md +105 -0
- package/skills/ai/ml-ops.md +169 -0
- package/skills/ai/orchestration-workflow.md +87 -0
- package/skills/ai/prompt-and-eval.md +114 -0
- package/skills/ai/prompt-optimizer.md +114 -0
- package/skills/ai/rag-system.md +104 -0
- package/skills/architecture/api-design.md +100 -0
- package/skills/architecture/caching.md +101 -0
- package/skills/architecture/cloud-native.md +97 -0
- package/skills/architecture/message-queue.md +100 -0
- package/skills/architecture/security-arch.md +105 -0
- package/skills/development/cpp.md +127 -0
- package/skills/development/go.md +129 -0
- package/skills/development/java.md +134 -0
- package/skills/development/kotlin.md +140 -0
- package/skills/development/mobile-crossplatform.md +144 -0
- package/skills/development/python.md +109 -0
- package/skills/development/rust.md +127 -0
- package/skills/development/shell.md +127 -0
- package/skills/development/swift.md +129 -0
- package/skills/development/typescript.md +129 -0
- package/skills/devops/ci-cd.md +108 -0
- package/skills/devops/containerization.md +106 -0
- package/skills/devops/cost-optimization.md +105 -0
- package/skills/devops/data-engineering.md +181 -0
- package/skills/devops/database.md +95 -0
- package/skills/devops/dependency-management.md +91 -0
- package/skills/devops/devsecops.md +96 -0
- package/skills/devops/git-workflow.md +100 -0
- package/skills/devops/incident-response.md +167 -0
- package/skills/devops/monorepo.md +87 -0
- package/skills/devops/observability.md +103 -0
- package/skills/devops/performance.md +104 -0
- package/skills/devops/testing.md +104 -0
- package/skills/docs/adr-workflow.md +32 -0
- package/skills/docs/backlog-proposal-workflow.md +19 -0
- package/skills/docs/customer-profile-workflow.md +22 -0
- package/skills/docs/evidence-ingest-workflow.md +23 -0
- package/skills/docs/init-docs.md +160 -0
- package/skills/docs/init-project.md +50 -0
- package/skills/docs/prd-workflow.md +57 -0
- package/skills/docs/prfaq-workflow.md +25 -0
- package/skills/docs/product-intelligence-review.md +22 -0
- package/skills/docs/product-intelligence-workflow.md +62 -0
- package/skills/docs/product-signal-workflow.md +27 -0
- package/skills/docs/research-workflow.md +28 -0
- package/skills/docs/runbook-workflow.md +24 -0
- package/skills/exploration/repo-map.md +297 -0
- package/skills/frameworks/django.md +159 -0
- package/skills/frameworks/nextjs.md +148 -0
- package/skills/frameworks/react.md +132 -0
- package/skills/frameworks/spring-boot.md +165 -0
- package/skills/frontend-design/accessibility.md +153 -0
- package/skills/frontend-design/component-patterns.md +111 -0
- package/skills/frontend-design/engineering.md +122 -0
- package/skills/frontend-design/state-management.md +118 -0
- package/skills/frontend-design/ui-aesthetics.md +102 -0
- package/skills/frontend-design/ux-principles.md +126 -0
- package/skills/quality-gates/review-work.md +90 -0
- package/skills/quality-gates/verify-change.md +94 -0
- package/skills/quality-gates/verify-module.md +96 -0
- package/skills/quality-gates/verify-quality.md +93 -0
- package/skills/quality-gates/verify-security.md +95 -0
- package/skills/roles/architect.ai-systems.md +37 -0
- package/skills/roles/architect.data.md +37 -0
- package/skills/roles/architect.enterprise.md +37 -0
- package/skills/roles/architect.integration.md +37 -0
- package/skills/roles/architect.md +68 -0
- package/skills/roles/architect.platform.md +37 -0
- package/skills/roles/data-analyst.experiment.md +37 -0
- package/skills/roles/data-analyst.md +68 -0
- package/skills/roles/data-analyst.product-intelligence.md +37 -0
- package/skills/roles/data-analyst.product.md +37 -0
- package/skills/roles/data-analyst.telemetry.md +37 -0
- package/skills/roles/data-engineer.pipeline.md +37 -0
- package/skills/roles/data-engineer.vector-retrieval.md +37 -0
- package/skills/roles/data-engineer.warehouse.md +37 -0
- package/skills/roles/debugger.md +68 -0
- package/skills/roles/designer.accessibility.md +43 -0
- package/skills/roles/designer.md +68 -0
- package/skills/roles/engineer.ai.md +49 -0
- package/skills/roles/engineer.data.md +49 -0
- package/skills/roles/engineer.md +85 -0
- package/skills/roles/engineer.platform.md +49 -0
- package/skills/roles/operator.docs.md +43 -0
- package/skills/roles/operator.md +68 -0
- package/skills/roles/operator.release.md +43 -0
- package/skills/roles/operator.sre.md +43 -0
- package/skills/roles/orchestrator.md +66 -0
- package/skills/roles/product-manager.ai-product.md +37 -0
- package/skills/roles/product-manager.business-strategy.md +43 -0
- package/skills/roles/product-manager.enterprise.md +37 -0
- package/skills/roles/product-manager.growth.md +37 -0
- package/skills/roles/product-manager.md +67 -0
- package/skills/roles/product-manager.platform.md +37 -0
- package/skills/roles/product-manager.product.md +37 -0
- package/skills/roles/qa.ai-eval.md +37 -0
- package/skills/roles/qa.api-contract.md +37 -0
- package/skills/roles/qa.data-pipeline.md +37 -0
- package/skills/roles/qa.md +68 -0
- package/skills/roles/qa.test-automation.md +49 -0
- package/skills/roles/qa.web-ui.md +37 -0
- package/skills/roles/researcher.explorer.md +43 -0
- package/skills/roles/researcher.md +68 -0
- package/skills/roles/researcher.ux.md +43 -0
- package/skills/roles/reviewer.devil-advocate.md +43 -0
- package/skills/roles/reviewer.evaluator.md +43 -0
- package/skills/roles/reviewer.md +68 -0
- package/skills/roles/reviewer.trace.md +43 -0
- package/skills/roles/security.ai.md +37 -0
- package/skills/roles/security.appsec.md +37 -0
- package/skills/roles/security.cloud.md +37 -0
- package/skills/roles/security.legal-compliance.md +49 -0
- package/skills/roles/security.md +68 -0
- package/skills/roles/security.privacy.md +37 -0
- package/skills/roles/security.supply-chain.md +37 -0
- package/skills/routing.md +139 -0
- package/skills/security/blue-team.md +83 -0
- package/skills/security/code-audit.md +94 -0
- package/skills/security/pentest.md +84 -0
- package/skills/security/red-team.md +81 -0
- package/skills/security/threat-intel.md +89 -0
- package/skills/security/vuln-research.md +87 -0
- package/skills/utility/clean-code.md +165 -0
- package/sync-agents.mjs +899 -0
- package/templates/docs/adr.md +27 -0
- package/templates/docs/backlog-proposal.md +26 -0
- package/templates/docs/customer-profile.md +34 -0
- package/templates/docs/evidence-brief.md +37 -0
- package/templates/docs/incident-report.md +46 -0
- package/templates/docs/memo.md +27 -0
- package/templates/docs/meta-prd.md +56 -0
- package/templates/docs/one-pager.md +24 -0
- package/templates/docs/prd-business.md +61 -0
- package/templates/docs/prd-platform.md +62 -0
- package/templates/docs/prd.md +47 -0
- package/templates/docs/prfaq.md +31 -0
- package/templates/docs/product-intelligence-report.md +31 -0
- package/templates/docs/research-brief.md +29 -0
- package/templates/docs/rfc-platform.md +60 -0
- package/templates/docs/rfc.md +46 -0
- package/templates/docs/runbook.md +33 -0
- package/templates/docs/signal-brief.md +25 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
skills/development/java.md — Java Best Practices — Use this skill when writing, reviewing, or debugging Java or Kotlin code on the
|
|
3
|
+
|
|
4
|
+
Use this skill when writing, reviewing, or debugging Java or Kotlin code on the JVM. ## Project Structure
|
|
5
|
+
-->
|
|
6
|
+
# Java Best Practices
|
|
7
|
+
|
|
8
|
+
Use this skill when writing, reviewing, or debugging Java or Kotlin code on the JVM.
|
|
9
|
+
|
|
10
|
+
## Project Structure
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
src/
|
|
14
|
+
main/
|
|
15
|
+
java/com/example/
|
|
16
|
+
controller/
|
|
17
|
+
service/
|
|
18
|
+
repository/
|
|
19
|
+
model/
|
|
20
|
+
config/
|
|
21
|
+
resources/
|
|
22
|
+
application.yml
|
|
23
|
+
test/
|
|
24
|
+
java/com/example/
|
|
25
|
+
controller/
|
|
26
|
+
service/
|
|
27
|
+
pom.xml or build.gradle.kts
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- Maven or Gradle for build management
|
|
31
|
+
- Follow standard Maven directory layout
|
|
32
|
+
- One class per file; package by feature when the project is large
|
|
33
|
+
|
|
34
|
+
## Tooling
|
|
35
|
+
|
|
36
|
+
| Tool | Purpose |
|
|
37
|
+
|---|---|
|
|
38
|
+
| javac / kotlinc | Compilation |
|
|
39
|
+
| Checkstyle / ktlint | Code style enforcement |
|
|
40
|
+
| SpotBugs / ErrorProne | Static analysis |
|
|
41
|
+
| JUnit 5 / Kotest | Testing |
|
|
42
|
+
| Mockito / MockK | Mocking |
|
|
43
|
+
| JaCoCo | Coverage |
|
|
44
|
+
| OWASP Dependency Check | Vulnerability scanning |
|
|
45
|
+
|
|
46
|
+
## Type Safety
|
|
47
|
+
|
|
48
|
+
- Use `Optional<T>` for values that may be absent; never return null from public methods
|
|
49
|
+
- Records (Java 16+) or data classes (Kotlin) for immutable value objects
|
|
50
|
+
- Sealed interfaces for closed type hierarchies
|
|
51
|
+
- Generics with bounded wildcards: `<? extends T>` for producers, `<? super T>` for consumers
|
|
52
|
+
- Avoid raw types; always parameterize generics
|
|
53
|
+
|
|
54
|
+
## Error Handling
|
|
55
|
+
|
|
56
|
+
- Use checked exceptions for recoverable conditions; unchecked for programming errors
|
|
57
|
+
- Custom exception hierarchy extending `RuntimeException` for domain errors
|
|
58
|
+
- Never catch `Exception` or `Throwable` unless at the top-level handler
|
|
59
|
+
- Include context: `throw new OrderNotFoundException("Order " + id + " not found")`
|
|
60
|
+
- Use try-with-resources for all `AutoCloseable` resources
|
|
61
|
+
- Log at the point of handling, not at the point of throwing
|
|
62
|
+
|
|
63
|
+
## Immutability
|
|
64
|
+
|
|
65
|
+
- Records (Java) or data classes (Kotlin) for immutable data
|
|
66
|
+
- `final` fields and classes by default
|
|
67
|
+
- `Collections.unmodifiableList()` or `List.of()` for immutable collections
|
|
68
|
+
- Avoid setters; use builder pattern or `with` methods that return new instances
|
|
69
|
+
- Kotlin: `val` over `var`; `listOf` over `mutableListOf` unless mutation is required
|
|
70
|
+
|
|
71
|
+
## Patterns
|
|
72
|
+
|
|
73
|
+
### Dependency Injection
|
|
74
|
+
- Constructor injection (not field injection)
|
|
75
|
+
- Spring: `@Component`, `@Service`, `@Repository` stereotypes
|
|
76
|
+
- Interface-based dependencies for testability
|
|
77
|
+
- Avoid circular dependencies; restructure if detected
|
|
78
|
+
|
|
79
|
+
### Repository Pattern
|
|
80
|
+
- Interface defines data access contract
|
|
81
|
+
- Implementation handles persistence details
|
|
82
|
+
- Spring Data: derive queries from method names; use `@Query` for complex queries
|
|
83
|
+
- Pageable for list operations
|
|
84
|
+
|
|
85
|
+
### Stream API
|
|
86
|
+
- Prefer streams over manual loops for collection processing
|
|
87
|
+
- `map`, `filter`, `collect` for transformations
|
|
88
|
+
- `Optional.map`/`flatMap` for null-safe chaining
|
|
89
|
+
- Avoid side effects in stream operations
|
|
90
|
+
- Use parallel streams only with benchmarking evidence
|
|
91
|
+
|
|
92
|
+
## Testing
|
|
93
|
+
|
|
94
|
+
- JUnit 5 with `@Test`, `@ParameterizedTest`, `@Nested`
|
|
95
|
+
- Mockito for mocking external dependencies
|
|
96
|
+
- `@SpringBootTest` for integration tests; `@WebMvcTest` for controller tests
|
|
97
|
+
- Testcontainers for database and infrastructure integration tests
|
|
98
|
+
- AssertJ for fluent assertions
|
|
99
|
+
- Test naming: `should_returnEmpty_when_noResultsMatch`
|
|
100
|
+
|
|
101
|
+
## Performance
|
|
102
|
+
|
|
103
|
+
- Profile with JFR (Java Flight Recorder) and JMC (Mission Control)
|
|
104
|
+
- GC tuning: choose G1 or ZGC based on latency requirements
|
|
105
|
+
- Connection pooling: HikariCP for database, Apache HttpClient for HTTP
|
|
106
|
+
- Avoid unnecessary object creation in hot paths
|
|
107
|
+
- Use `StringBuilder` for string concatenation in loops
|
|
108
|
+
- JMH for microbenchmarks
|
|
109
|
+
|
|
110
|
+
## Spring Boot Specifics
|
|
111
|
+
|
|
112
|
+
- Externalize configuration: `application.yml` with profiles
|
|
113
|
+
- Actuator endpoints for health, metrics, and info
|
|
114
|
+
- Use `@ConfigurationProperties` over `@Value` for structured config
|
|
115
|
+
- Validate configuration with `@Validated`
|
|
116
|
+
- Global exception handler with `@ControllerAdvice`
|
|
117
|
+
|
|
118
|
+
## Security
|
|
119
|
+
|
|
120
|
+
- Spring Security for authentication and authorization
|
|
121
|
+
- Parameterized queries via JPA or Spring JDBC
|
|
122
|
+
- Input validation with Bean Validation (`@Valid`, `@NotNull`, `@Size`)
|
|
123
|
+
- OWASP Dependency Check in CI
|
|
124
|
+
- Never log sensitive data; mask PII in logs
|
|
125
|
+
- Use BCrypt for password hashing
|
|
126
|
+
|
|
127
|
+
## Anti-Patterns
|
|
128
|
+
|
|
129
|
+
- Service locator instead of dependency injection
|
|
130
|
+
- God classes with mixed responsibilities
|
|
131
|
+
- Catch-and-ignore empty catch blocks
|
|
132
|
+
- Null returns instead of `Optional`
|
|
133
|
+
- Mutable DTOs shared across layers
|
|
134
|
+
- Over-engineering: unnecessary abstract factories and strategy patterns
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
skills/development/kotlin.md — Kotlin / Android Development — | Scope | Use when |
|
|
3
|
+
|
|
4
|
+
## Coroutines & Flows ### Coroutine scope discipline
|
|
5
|
+
-->
|
|
6
|
+
# Kotlin / Android Development
|
|
7
|
+
|
|
8
|
+
## Coroutines & Flows
|
|
9
|
+
|
|
10
|
+
### Coroutine scope discipline
|
|
11
|
+
|
|
12
|
+
| Scope | Use when |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `viewModelScope` | ViewModel-bound work; auto-cancelled on clear |
|
|
15
|
+
| `lifecycleScope` | Fragment/Activity-bound; cancelled on destroy |
|
|
16
|
+
| `rememberCoroutineScope()` | Compose-scoped; cancelled on composition exit |
|
|
17
|
+
| `GlobalScope` | Never — uncontrolled lifetime |
|
|
18
|
+
|
|
19
|
+
```kotlin
|
|
20
|
+
class ItemViewModel(private val repo: ItemRepository) : ViewModel() {
|
|
21
|
+
private val _items = MutableStateFlow<List<Item>>(emptyList())
|
|
22
|
+
val items: StateFlow<List<Item>> = _items.asStateFlow()
|
|
23
|
+
|
|
24
|
+
init {
|
|
25
|
+
viewModelScope.launch {
|
|
26
|
+
repo.itemsFlow().collect { _items.value = it }
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Flow operators
|
|
33
|
+
|
|
34
|
+
- `stateIn(scope, SharingStarted.WhileSubscribed(5_000), initial)` — converts cold flow to hot StateFlow for UI consumption
|
|
35
|
+
- `map`, `filter`, `distinctUntilChanged`, `debounce` for transform chains
|
|
36
|
+
- `combine` for merging multiple flows
|
|
37
|
+
- Use `flowOn(Dispatchers.IO)` for upstream CPU/IO work; do not switch dispatchers in the collector
|
|
38
|
+
|
|
39
|
+
### Dispatcher guidelines
|
|
40
|
+
|
|
41
|
+
| Dispatcher | Use for |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `Dispatchers.Main` | UI updates |
|
|
44
|
+
| `Dispatchers.IO` | Network, disk, database |
|
|
45
|
+
| `Dispatchers.Default` | CPU-intensive work |
|
|
46
|
+
| `Dispatchers.Unconfined` | Rarely — only in tests |
|
|
47
|
+
|
|
48
|
+
## Jetpack Compose
|
|
49
|
+
|
|
50
|
+
### State hoisting
|
|
51
|
+
|
|
52
|
+
Hoist state to the lowest common owner. Stateless composables receive state and callbacks:
|
|
53
|
+
|
|
54
|
+
```kotlin
|
|
55
|
+
@Composable
|
|
56
|
+
fun ItemList(items: List<Item>, onDelete: (Item) -> Unit) { ... }
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Side effects
|
|
60
|
+
|
|
61
|
+
| Effect | Use when |
|
|
62
|
+
|---|---|
|
|
63
|
+
| `LaunchedEffect(key)` | Coroutine that re-launches when key changes |
|
|
64
|
+
| `SideEffect` | Sync non-Compose state each recomposition |
|
|
65
|
+
| `DisposableEffect(key)` | Setup/teardown with cleanup |
|
|
66
|
+
| `rememberUpdatedState` | Capture latest lambda in long-lived effect |
|
|
67
|
+
|
|
68
|
+
### Performance
|
|
69
|
+
|
|
70
|
+
- `remember` expensive computations with stable keys
|
|
71
|
+
- `key(id) { ... }` in lazy lists to preserve item identity
|
|
72
|
+
- Avoid unstable lambdas — use `remember { { ... } }` or stable function references
|
|
73
|
+
- Enable Compose compiler metrics to detect recomposition hot spots
|
|
74
|
+
- Prefer `LazyColumn` over `Column` for variable-length lists
|
|
75
|
+
|
|
76
|
+
## Architecture: Clean + MVVM
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
UI Layer (Composables) → ViewModel (StateFlow) → Domain (UseCases) → Data (Repository) → API / DB
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- Domain layer is pure Kotlin, no Android dependencies
|
|
83
|
+
- Repository abstracts data sources; returns `Flow` or `Result`
|
|
84
|
+
- UseCases wrap single business operations; testable in isolation
|
|
85
|
+
|
|
86
|
+
## Testing
|
|
87
|
+
|
|
88
|
+
### Unit tests (JUnit 5 + MockK)
|
|
89
|
+
|
|
90
|
+
```kotlin
|
|
91
|
+
@Test
|
|
92
|
+
fun `fetchItems returns mapped items`() = runTest {
|
|
93
|
+
val repo = mockk<ItemRepository>()
|
|
94
|
+
coEvery { repo.fetchAll() } returns listOf(Item(id = "1", title = "Test"))
|
|
95
|
+
val vm = ItemViewModel(repo)
|
|
96
|
+
assertEquals(1, vm.items.value.size)
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
- Use `runTest` from `kotlinx-coroutines-test` for coroutine unit tests
|
|
101
|
+
- `advanceUntilIdle()` to drain pending coroutines
|
|
102
|
+
- `turbine` library for Flow assertion (`flow.test { assertItem() }`)
|
|
103
|
+
|
|
104
|
+
### UI tests (Compose testing)
|
|
105
|
+
|
|
106
|
+
```kotlin
|
|
107
|
+
composeTestRule.onNodeWithText("Submit").performClick()
|
|
108
|
+
composeTestRule.onNodeWithTag("result").assertIsDisplayed()
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- Prefer semantic matchers (`onNodeWithContentDescription`) over positional
|
|
112
|
+
- Use `createComposeRule()` for isolated component tests
|
|
113
|
+
|
|
114
|
+
## Dependency Injection
|
|
115
|
+
|
|
116
|
+
Use **Hilt** (Dagger-backed) for Android projects. Annotate entry points correctly:
|
|
117
|
+
|
|
118
|
+
```kotlin
|
|
119
|
+
@HiltViewModel
|
|
120
|
+
class ItemViewModel @Inject constructor(
|
|
121
|
+
private val repo: ItemRepository
|
|
122
|
+
) : ViewModel()
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Scoping: `@Singleton` for app-scoped, `@ActivityRetainedScoped` for ViewModel-lived, `@ActivityScoped` for Activity-lived.
|
|
126
|
+
|
|
127
|
+
## Build & Tooling
|
|
128
|
+
|
|
129
|
+
- **Gradle Version Catalogs** (`libs.versions.toml`) for dependency management
|
|
130
|
+
- Enable R8 / ProGuard in release builds for shrinking and obfuscation
|
|
131
|
+
- **Kotlin Symbol Processing (KSP)** instead of KAPT for annotation processing
|
|
132
|
+
- `detekt` for static analysis; `ktlint` for formatting
|
|
133
|
+
- Minimum SDK: follow Play Store distribution requirements (API 26+ covers ~95%)
|
|
134
|
+
|
|
135
|
+
## Common Pitfalls
|
|
136
|
+
|
|
137
|
+
- `collect` in `Fragment.onViewCreated` without `repeatOnLifecycle(STARTED)` — causes collection after view destruction
|
|
138
|
+
- `StateFlow.value` reads in tests without collecting — use `turbine` or `runTest { first() }`
|
|
139
|
+
- Leaking `Activity` context into long-lived objects — use `applicationContext`
|
|
140
|
+
- `LazyColumn` with `items(list)` where `list` is `State<List<...>>` causing full recomposition — use `key` param
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
skills/development/mobile-crossplatform.md — Mobile Cross-Platform Development — Before choosing a framework, answer:
|
|
3
|
+
|
|
4
|
+
## Decision Framework: Native vs Cross-Platform Before choosing a framework, answer:
|
|
5
|
+
-->
|
|
6
|
+
# Mobile Cross-Platform Development
|
|
7
|
+
|
|
8
|
+
## Decision Framework: Native vs Cross-Platform
|
|
9
|
+
|
|
10
|
+
Before choosing a framework, answer:
|
|
11
|
+
|
|
12
|
+
| Question | Leans native | Leans cross-platform |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| Platform-specific APIs needed (ARKit, Health, NFC)? | Yes | No |
|
|
15
|
+
| Animation fidelity is a differentiator? | Yes | Partial |
|
|
16
|
+
| Single team, both platforms? | — | Yes |
|
|
17
|
+
| Heavy use of platform OS widgets? | Yes | No |
|
|
18
|
+
| App is primarily data-display / CRUD? | — | Yes |
|
|
19
|
+
| Existing web team? | — | React Native |
|
|
20
|
+
| Existing Kotlin/Swift team? | Native | — |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Flutter
|
|
25
|
+
|
|
26
|
+
**Runtime:** Dart compiled to native ARM; Skia/Impeller rendering engine (no platform widgets by default).
|
|
27
|
+
|
|
28
|
+
**Best for:** pixel-perfect UI consistency across iOS/Android/web/desktop from a single codebase. Strong for teams without web background.
|
|
29
|
+
|
|
30
|
+
### Architecture pattern: BLoC / Riverpod
|
|
31
|
+
|
|
32
|
+
```dart
|
|
33
|
+
@riverpod
|
|
34
|
+
Future<List<Item>> items(ItemsRef ref) async {
|
|
35
|
+
return ref.watch(repositoryProvider).fetchAll();
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- `riverpod` for dependency injection and async state
|
|
40
|
+
- `BLoC` for complex event-driven state machines
|
|
41
|
+
- Avoid `StatefulWidget` + `setState` beyond leaf components
|
|
42
|
+
|
|
43
|
+
### Performance
|
|
44
|
+
|
|
45
|
+
- `const` constructors everywhere possible — eliminates widget rebuilds
|
|
46
|
+
- `RepaintBoundary` around independently-animated subtrees
|
|
47
|
+
- Profile with Flutter DevTools → CPU flame chart + widget rebuild tracker
|
|
48
|
+
- `ListView.builder` for lazy lists; never `ListView(children: [...])` for long lists
|
|
49
|
+
|
|
50
|
+
### Testing
|
|
51
|
+
|
|
52
|
+
```dart
|
|
53
|
+
testWidgets('shows items on load', (tester) async {
|
|
54
|
+
await tester.pumpWidget(ProviderScope(child: ItemList()));
|
|
55
|
+
await tester.pumpAndSettle();
|
|
56
|
+
expect(find.text('Item 1'), findsOneWidget);
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- `flutter_test` for widget tests (fast, no device needed)
|
|
61
|
+
- `integration_test` for E2E on real device / emulator
|
|
62
|
+
- `mocktail` or `mockito` for mocking
|
|
63
|
+
|
|
64
|
+
### Tooling
|
|
65
|
+
|
|
66
|
+
- `flutter analyze` + `dart format`
|
|
67
|
+
- `very_good_cli` for project scaffolding with opinionated defaults
|
|
68
|
+
- `flutter_flavorizr` for environment flavors (dev/staging/prod)
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## React Native
|
|
73
|
+
|
|
74
|
+
**Runtime:** JavaScript/TypeScript on Hermes engine; bridges to native views via the New Architecture (JSI + Fabric).
|
|
75
|
+
|
|
76
|
+
**Best for:** Teams with React web experience sharing logic/types between web and mobile.
|
|
77
|
+
|
|
78
|
+
### New Architecture (React Native 0.74+)
|
|
79
|
+
|
|
80
|
+
Enable the New Architecture by default on new projects. Key changes:
|
|
81
|
+
- JSI replaces the async bridge — sync native calls
|
|
82
|
+
- Fabric replaces the native renderer — concurrent React features work correctly
|
|
83
|
+
- TurboModules replace native modules
|
|
84
|
+
|
|
85
|
+
### State & logic sharing with web
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
// Shared hook — works in React Native and React web
|
|
89
|
+
export function useItems() {
|
|
90
|
+
const { data } = useQuery({ queryKey: ['items'], queryFn: fetchItems });
|
|
91
|
+
return data ?? [];
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- Share: types, API clients, business logic hooks, validation schemas
|
|
96
|
+
- Do not share: navigation, platform-specific UI, native module wrappers
|
|
97
|
+
|
|
98
|
+
### Navigation
|
|
99
|
+
|
|
100
|
+
Use **Expo Router** (file-based) for new projects or **React Navigation** (stack/tab/drawer) for maximum control:
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
// expo-router
|
|
104
|
+
export default function ItemScreen() { ... }
|
|
105
|
+
// file: app/items/[id].tsx → /items/:id
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Performance
|
|
109
|
+
|
|
110
|
+
- Use the Hermes profiler to find JS thread bottlenecks
|
|
111
|
+
- Move heavy computation to native modules or worklets (`react-native-reanimated`)
|
|
112
|
+
- `FlatList` with `getItemLayout` for fixed-height rows; `FlashList` for variable heights
|
|
113
|
+
- Enable `useMemo` / `useCallback` sparingly and only after measuring
|
|
114
|
+
|
|
115
|
+
### Expo vs bare React Native
|
|
116
|
+
|
|
117
|
+
| | Expo (managed) | Bare RN |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| Setup speed | Fast | Slower |
|
|
120
|
+
| Custom native code | EAS custom builds | Full control |
|
|
121
|
+
| Over-the-air updates | Expo Updates | Manual setup |
|
|
122
|
+
| Recommended for | Most new projects | Deep native integration |
|
|
123
|
+
|
|
124
|
+
### Testing
|
|
125
|
+
|
|
126
|
+
- `@testing-library/react-native` for component tests
|
|
127
|
+
- `Detox` or `Maestro` for E2E
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Common Pitfalls (both frameworks)
|
|
132
|
+
|
|
133
|
+
- **Deep linking not tested until late** — set up universal links / app links in week 1
|
|
134
|
+
- **Push notifications complexity** — Expo Notifications or Firebase Cloud Messaging; plan for permission states
|
|
135
|
+
- **Over-the-air update strategy** — define what can be OTA vs what requires App Store review
|
|
136
|
+
- **Platform capability divergence** — features available on iOS 17+ may be absent on Android 12; maintain a capability matrix
|
|
137
|
+
- **Code signing automation** — `fastlane match` (iOS) and keystore management (Android) require upfront investment; do it early
|
|
138
|
+
|
|
139
|
+
## When to go native anyway
|
|
140
|
+
|
|
141
|
+
- Camera pipelines, real-time audio/video processing
|
|
142
|
+
- Tight OS integration (CarPlay, watchOS, Android Auto)
|
|
143
|
+
- Games or high-frame-rate interactive graphics
|
|
144
|
+
- Health / fitness sensors with continuous background access
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
skills/development/python.md — Python Best Practices — Use this skill when writing, reviewing, or debugging Python code.
|
|
3
|
+
|
|
4
|
+
Use this skill when writing, reviewing, or debugging Python code. ## Project Structure
|
|
5
|
+
-->
|
|
6
|
+
# Python Best Practices
|
|
7
|
+
|
|
8
|
+
Use this skill when writing, reviewing, or debugging Python code.
|
|
9
|
+
|
|
10
|
+
## Project Structure
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
src/
|
|
14
|
+
package_name/
|
|
15
|
+
__init__.py
|
|
16
|
+
models.py
|
|
17
|
+
services.py
|
|
18
|
+
utils.py
|
|
19
|
+
tests/
|
|
20
|
+
test_models.py
|
|
21
|
+
test_services.py
|
|
22
|
+
conftest.py
|
|
23
|
+
pyproject.toml
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- Use `pyproject.toml` as the single source for project metadata and tool config
|
|
27
|
+
- `src/` layout to prevent accidental imports from the working directory
|
|
28
|
+
- One module per concern; keep files under 400 lines
|
|
29
|
+
|
|
30
|
+
## Tooling
|
|
31
|
+
|
|
32
|
+
| Tool | Purpose |
|
|
33
|
+
|---|---|
|
|
34
|
+
| uv / poetry / pip | Dependency management |
|
|
35
|
+
| ruff | Linting and formatting (replaces flake8, isort, black) |
|
|
36
|
+
| mypy / pyright | Static type checking |
|
|
37
|
+
| pytest | Testing |
|
|
38
|
+
| coverage | Test coverage |
|
|
39
|
+
| bandit | Security scanning |
|
|
40
|
+
|
|
41
|
+
## Type Hints
|
|
42
|
+
|
|
43
|
+
- Type all function signatures: parameters and return types
|
|
44
|
+
- Use `from __future__ import annotations` for modern syntax in older Pythons
|
|
45
|
+
- Prefer `str | None` over `Optional[str]`
|
|
46
|
+
- Use `TypeAlias`, `TypeVar`, and `Protocol` for complex type patterns
|
|
47
|
+
- Run mypy or pyright in CI with strict mode
|
|
48
|
+
|
|
49
|
+
## Error Handling
|
|
50
|
+
|
|
51
|
+
- Catch specific exceptions, never bare `except:`
|
|
52
|
+
- Use custom exception classes for domain-specific errors
|
|
53
|
+
- Context managers (`with`) for resource cleanup
|
|
54
|
+
- `logging.exception()` in catch blocks to preserve stack trace
|
|
55
|
+
- Return early on validation failures; avoid deep nesting
|
|
56
|
+
|
|
57
|
+
## Patterns
|
|
58
|
+
|
|
59
|
+
### Dataclasses and Pydantic
|
|
60
|
+
- `dataclass(frozen=True)` for immutable value objects
|
|
61
|
+
- Pydantic `BaseModel` for input validation and serialization
|
|
62
|
+
- Avoid plain dicts for structured data that crosses function boundaries
|
|
63
|
+
|
|
64
|
+
### Async
|
|
65
|
+
- Use `asyncio` for I/O-bound concurrency
|
|
66
|
+
- `async with` for resource management in async contexts
|
|
67
|
+
- Never mix `asyncio` and threading without careful isolation
|
|
68
|
+
- Use `asyncio.gather` for concurrent I/O operations
|
|
69
|
+
- Set timeouts on all async operations
|
|
70
|
+
|
|
71
|
+
### Dependencies
|
|
72
|
+
- Pin exact versions in lock file
|
|
73
|
+
- Use virtual environments always
|
|
74
|
+
- Separate dev, test, and production dependencies
|
|
75
|
+
- Audit with `pip audit` or `safety check`
|
|
76
|
+
|
|
77
|
+
## Testing
|
|
78
|
+
|
|
79
|
+
- pytest with fixtures for setup and teardown
|
|
80
|
+
- `conftest.py` for shared fixtures scoped to the directory
|
|
81
|
+
- `@pytest.mark.parametrize` for data-driven tests
|
|
82
|
+
- `unittest.mock.patch` for external dependency isolation
|
|
83
|
+
- Test async code with `pytest-asyncio`
|
|
84
|
+
- Target 80% branch coverage minimum
|
|
85
|
+
|
|
86
|
+
## Performance
|
|
87
|
+
|
|
88
|
+
- Profile before optimizing: `cProfile`, `py-spy`, or `scalene`
|
|
89
|
+
- Use generators for large data processing (lazy evaluation)
|
|
90
|
+
- `functools.lru_cache` for expensive pure functions
|
|
91
|
+
- Avoid global mutable state
|
|
92
|
+
- Use list/dict/set comprehensions over manual loops when readable
|
|
93
|
+
- Consider `numpy` or `polars` for numerical and tabular data
|
|
94
|
+
|
|
95
|
+
## Security
|
|
96
|
+
|
|
97
|
+
- Never use `eval()`, `exec()`, or `pickle.loads()` on untrusted input
|
|
98
|
+
- Use `subprocess` with `shell=False` and explicit argument lists
|
|
99
|
+
- Validate all external input with Pydantic or equivalent
|
|
100
|
+
- Use `secrets` module for cryptographic randomness, not `random`
|
|
101
|
+
- Keep dependencies updated; automate vulnerability scanning
|
|
102
|
+
|
|
103
|
+
## Anti-Patterns
|
|
104
|
+
|
|
105
|
+
- Mutable default arguments (`def f(x=[])`): use `None` and create inside
|
|
106
|
+
- Broad exception handling: catch what you can handle
|
|
107
|
+
- Circular imports: restructure modules or use lazy imports
|
|
108
|
+
- Star imports (`from module import *`): pollutes namespace
|
|
109
|
+
- Global mutable state: use dependency injection or module-level constants
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
skills/development/rust.md — Rust Best Practices — Use this skill when writing, reviewing, or debugging Rust code.
|
|
3
|
+
|
|
4
|
+
Use this skill when writing, reviewing, or debugging Rust code. ## Project Structure
|
|
5
|
+
-->
|
|
6
|
+
# Rust Best Practices
|
|
7
|
+
|
|
8
|
+
Use this skill when writing, reviewing, or debugging Rust code.
|
|
9
|
+
|
|
10
|
+
## Project Structure
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
src/
|
|
14
|
+
main.rs or lib.rs
|
|
15
|
+
models/
|
|
16
|
+
mod.rs
|
|
17
|
+
services/
|
|
18
|
+
mod.rs
|
|
19
|
+
handlers/
|
|
20
|
+
mod.rs
|
|
21
|
+
error.rs
|
|
22
|
+
tests/
|
|
23
|
+
integration_tests.rs
|
|
24
|
+
Cargo.toml
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- Binary crates use `main.rs`; libraries use `lib.rs`
|
|
28
|
+
- `mod.rs` or named module files for submodules
|
|
29
|
+
- Keep `main.rs` thin: parse args, build app, run
|
|
30
|
+
- Integration tests in `tests/` directory; unit tests inline with `#[cfg(test)]`
|
|
31
|
+
|
|
32
|
+
## Tooling
|
|
33
|
+
|
|
34
|
+
| Tool | Purpose |
|
|
35
|
+
|---|---|
|
|
36
|
+
| rustfmt | Formatting |
|
|
37
|
+
| clippy | Linting with actionable suggestions |
|
|
38
|
+
| cargo test | Testing |
|
|
39
|
+
| cargo bench | Benchmarking |
|
|
40
|
+
| cargo audit | Dependency vulnerability scanning |
|
|
41
|
+
| miri | Undefined behavior detection |
|
|
42
|
+
|
|
43
|
+
## Ownership and Borrowing
|
|
44
|
+
|
|
45
|
+
- Prefer borrowing (`&T`, `&mut T`) over ownership transfer when the caller keeps the data
|
|
46
|
+
- Use `Clone` sparingly; understand the cost
|
|
47
|
+
- Prefer `&str` over `String` in function parameters when no ownership is needed
|
|
48
|
+
- Use `Cow<'_, str>` when a function may or may not need to allocate
|
|
49
|
+
- Lifetime annotations: name them meaningfully when multiple lifetimes interact
|
|
50
|
+
|
|
51
|
+
## Error Handling
|
|
52
|
+
|
|
53
|
+
- Use `Result<T, E>` for recoverable errors
|
|
54
|
+
- Define a crate-level error enum with `thiserror`
|
|
55
|
+
- Use `anyhow` for application code where error types are less important
|
|
56
|
+
- The `?` operator for propagation; add context with `.context("message")`
|
|
57
|
+
- `panic!` only for programming errors (invariant violations), never for expected failures
|
|
58
|
+
- Avoid `unwrap()` outside tests; use `expect("reason")` if failure is a bug
|
|
59
|
+
|
|
60
|
+
## Patterns
|
|
61
|
+
|
|
62
|
+
### Builder Pattern
|
|
63
|
+
- Use for types with many optional parameters
|
|
64
|
+
- `TypeBuilder::new().field(value).build() -> Result<Type>`
|
|
65
|
+
- Validate in `build()`, not in individual setters
|
|
66
|
+
|
|
67
|
+
### Type-State Pattern
|
|
68
|
+
- Encode state transitions in the type system
|
|
69
|
+
- Prevents invalid state at compile time
|
|
70
|
+
- Use for protocols, workflows, and configuration
|
|
71
|
+
|
|
72
|
+
### Newtype Pattern
|
|
73
|
+
- Wrap primitive types to add type safety: `struct UserId(u64)`
|
|
74
|
+
- Prevents mixing up parameters of the same underlying type
|
|
75
|
+
- Implement `Deref` selectively; prefer explicit conversion methods
|
|
76
|
+
|
|
77
|
+
## Async Rust
|
|
78
|
+
|
|
79
|
+
- Use `tokio` for async runtime (or `async-std` if the project uses it)
|
|
80
|
+
- `async fn` for I/O-bound operations
|
|
81
|
+
- Avoid blocking in async context; use `tokio::task::spawn_blocking` for CPU work
|
|
82
|
+
- Use `tokio::select!` for concurrent operations with cancellation
|
|
83
|
+
- Structured concurrency with `JoinSet` or `tokio::join!`
|
|
84
|
+
- Set timeouts on all async operations: `tokio::time::timeout`
|
|
85
|
+
|
|
86
|
+
## Testing
|
|
87
|
+
|
|
88
|
+
- Unit tests in the same file as the code: `#[cfg(test)] mod tests`
|
|
89
|
+
- Integration tests in `tests/` directory
|
|
90
|
+
- Use `#[test]` and `assert_eq!`, `assert!`
|
|
91
|
+
- Property-based testing with `proptest` for complex invariants
|
|
92
|
+
- `#[tokio::test]` for async tests
|
|
93
|
+
- Mock traits with `mockall` or manual test doubles
|
|
94
|
+
- Run `cargo test` and `cargo clippy` in CI
|
|
95
|
+
|
|
96
|
+
## Performance
|
|
97
|
+
|
|
98
|
+
- Zero-cost abstractions: iterators, generics, traits have no runtime overhead
|
|
99
|
+
- Use iterators over manual loops; they optimize well
|
|
100
|
+
- `Vec::with_capacity` when the size is known
|
|
101
|
+
- Avoid `Box<dyn Trait>` in hot paths; prefer generics for static dispatch
|
|
102
|
+
- Benchmark with `criterion` for statistical rigor
|
|
103
|
+
- Profile with `perf`, `flamegraph`, or `cargo-instruments`
|
|
104
|
+
|
|
105
|
+
## Unsafe
|
|
106
|
+
|
|
107
|
+
- Minimize `unsafe` blocks; document the safety invariant as a comment
|
|
108
|
+
- Prefer safe abstractions that encapsulate `unsafe` internally
|
|
109
|
+
- Run Miri on unsafe code: `cargo +nightly miri test`
|
|
110
|
+
- Review all `unsafe` blocks during code review with extra scrutiny
|
|
111
|
+
- Use `#[deny(unsafe_code)]` at the crate level when possible
|
|
112
|
+
|
|
113
|
+
## Security
|
|
114
|
+
|
|
115
|
+
- `cargo audit` in CI to check for vulnerable dependencies
|
|
116
|
+
- Use `secrecy` crate for secret values (prevents accidental logging)
|
|
117
|
+
- Validate all external input at boundaries
|
|
118
|
+
- Use `ring` or `rustcrypto` for cryptographic operations
|
|
119
|
+
- Pin dependency versions in `Cargo.lock` (commit it for binaries)
|
|
120
|
+
|
|
121
|
+
## Anti-Patterns
|
|
122
|
+
|
|
123
|
+
- Overusing `clone()` to satisfy the borrow checker without understanding ownership
|
|
124
|
+
- `unwrap()` in production code paths
|
|
125
|
+
- Excessive lifetimes when owned types would be simpler
|
|
126
|
+
- Fighting the borrow checker with `Rc<RefCell<T>>` everywhere
|
|
127
|
+
- Premature optimization with `unsafe` when safe code is fast enough
|