@cubis/foundry 0.3.70 → 0.3.72
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/CHANGELOG.md +15 -0
- package/dist/cli/core.js +4 -18
- package/dist/cli/core.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/core.ts +4 -18
- package/workflows/powers/accessibility/POWER.md +83 -94
- package/workflows/powers/accessibility/SKILL.md +82 -94
- package/workflows/powers/agent-design/POWER.md +201 -0
- package/workflows/powers/agent-design/SKILL.md +198 -0
- package/workflows/powers/agent-design/references/clarification-patterns.md +153 -0
- package/workflows/powers/agent-design/references/skill-testing.md +164 -0
- package/workflows/powers/agent-design/references/workflow-patterns.md +226 -0
- package/workflows/powers/agentic-eval/POWER.md +62 -0
- package/workflows/powers/agentic-eval/SKILL.md +59 -0
- package/workflows/powers/agentic-eval/references/rubric-and-regression-checklist.md +11 -0
- package/workflows/powers/api-designer/POWER.md +43 -71
- package/workflows/powers/api-designer/SKILL.md +43 -71
- package/workflows/powers/api-patterns/POWER.md +42 -56
- package/workflows/powers/api-patterns/SKILL.md +42 -57
- package/workflows/powers/architecture-designer/POWER.md +43 -60
- package/workflows/powers/architecture-designer/SKILL.md +43 -60
- package/workflows/powers/ask-questions-if-underspecified/POWER.md +51 -3
- package/workflows/powers/ask-questions-if-underspecified/SKILL.md +51 -3
- package/workflows/powers/auth-architect/POWER.md +69 -0
- package/workflows/powers/auth-architect/SKILL.md +66 -0
- package/workflows/powers/auth-architect/references/session-token-policy-checklist.md +45 -0
- package/workflows/powers/behavioral-modes/POWER.md +100 -9
- package/workflows/powers/behavioral-modes/SKILL.md +100 -9
- package/workflows/powers/c-pro/POWER.md +105 -0
- package/workflows/powers/c-pro/SKILL.md +102 -0
- package/workflows/powers/c-pro/references/build-systems-and-toolchains.md +148 -0
- package/workflows/powers/c-pro/references/common-ub-and-portability.md +166 -0
- package/workflows/powers/c-pro/references/debugging-with-sanitizers.md +205 -0
- package/workflows/powers/c-pro/references/memory-safety-and-build-checklist.md +60 -0
- package/workflows/powers/c-pro/references/posix-and-platform-apis.md +244 -0
- package/workflows/powers/changelog-generator/POWER.md +127 -63
- package/workflows/powers/changelog-generator/SKILL.md +126 -63
- package/workflows/powers/ci-cd-pipelines/POWER.md +156 -0
- package/workflows/powers/ci-cd-pipelines/SKILL.md +153 -0
- package/workflows/powers/ci-cd-pipelines/references/github-actions-patterns.md +160 -0
- package/workflows/powers/ci-cd-pipelines/references/pipeline-security-checklist.md +57 -0
- package/workflows/powers/cli-developer/POWER.md +152 -95
- package/workflows/powers/cli-developer/SKILL.md +152 -95
- package/workflows/powers/cpp-pro/POWER.md +111 -0
- package/workflows/powers/cpp-pro/SKILL.md +108 -0
- package/workflows/powers/cpp-pro/references/concurrency-primitives.md +266 -0
- package/workflows/powers/cpp-pro/references/move-semantics-and-value-types.md +149 -0
- package/workflows/powers/cpp-pro/references/performance-and-profiling.md +191 -0
- package/workflows/powers/cpp-pro/references/raii-and-modern-cpp-checklist.md +87 -0
- package/workflows/powers/cpp-pro/references/template-and-concepts-patterns.md +205 -0
- package/workflows/powers/csharp-pro/POWER.md +47 -22
- package/workflows/powers/csharp-pro/SKILL.md +47 -22
- package/workflows/powers/dart-pro/POWER.md +68 -0
- package/workflows/powers/dart-pro/SKILL.md +65 -0
- package/workflows/powers/dart-pro/references/isolate-and-concurrency.md +180 -0
- package/workflows/powers/dart-pro/references/null-safety-and-async-patterns.md +133 -0
- package/workflows/powers/dart-pro/references/package-structure-and-linting.md +193 -0
- package/workflows/powers/dart-pro/references/sealed-records-patterns.md +173 -0
- package/workflows/powers/dart-pro/references/testing-and-mocking.md +235 -0
- package/workflows/powers/database-design/POWER.md +47 -33
- package/workflows/powers/database-design/SKILL.md +47 -33
- package/workflows/powers/database-optimizer/POWER.md +43 -64
- package/workflows/powers/database-optimizer/SKILL.md +43 -64
- package/workflows/powers/database-skills/POWER.md +59 -93
- package/workflows/powers/database-skills/SKILL.md +59 -93
- package/workflows/powers/debugging-strategies/POWER.md +69 -0
- package/workflows/powers/debugging-strategies/SKILL.md +66 -0
- package/workflows/powers/debugging-strategies/references/reproduce-isolate-verify-checklist.md +42 -0
- package/workflows/powers/deep-research/POWER.md +67 -0
- package/workflows/powers/deep-research/SKILL.md +64 -0
- package/workflows/powers/deep-research/references/multi-round-research-loop.md +80 -0
- package/workflows/powers/design-system-builder/POWER.md +130 -116
- package/workflows/powers/design-system-builder/SKILL.md +130 -116
- package/workflows/powers/devops-engineer/POWER.md +120 -57
- package/workflows/powers/devops-engineer/SKILL.md +120 -57
- package/workflows/powers/docker-kubernetes/POWER.md +94 -0
- package/workflows/powers/docker-kubernetes/SKILL.md +91 -0
- package/workflows/powers/docker-kubernetes/references/dockerfile-optimization-checklist.md +35 -0
- package/workflows/powers/docker-kubernetes/references/kubernetes-deployment-patterns.md +59 -0
- package/workflows/powers/documentation-templates/POWER.md +158 -127
- package/workflows/powers/documentation-templates/SKILL.md +158 -127
- package/workflows/powers/drizzle-expert/POWER.md +66 -0
- package/workflows/powers/drizzle-expert/SKILL.md +63 -0
- package/workflows/powers/drizzle-expert/references/runtime-pairing-matrix.md +16 -0
- package/workflows/powers/drizzle-expert/references/schema-and-migration-playbook.md +18 -0
- package/workflows/powers/error-ux-observability/POWER.md +144 -131
- package/workflows/powers/error-ux-observability/SKILL.md +143 -131
- package/workflows/powers/fastapi-expert/POWER.md +46 -60
- package/workflows/powers/fastapi-expert/SKILL.md +46 -60
- package/workflows/powers/firebase/POWER.md +65 -0
- package/workflows/powers/firebase/SKILL.md +62 -0
- package/workflows/powers/firebase/references/platform-routing.md +16 -0
- package/workflows/powers/firebase/references/rules-and-indexes-checklist.md +11 -0
- package/workflows/powers/flutter-design-system/POWER.md +63 -0
- package/workflows/powers/flutter-design-system/SKILL.md +60 -0
- package/workflows/powers/flutter-design-system/references/shared-widgets.md +29 -0
- package/workflows/powers/flutter-design-system/references/tokens-and-theme.md +34 -0
- package/workflows/powers/flutter-drift/POWER.md +65 -0
- package/workflows/powers/flutter-drift/SKILL.md +62 -0
- package/workflows/powers/flutter-drift/references/migrations.md +22 -0
- package/workflows/powers/flutter-drift/references/query-patterns.md +26 -0
- package/workflows/powers/flutter-feature/POWER.md +65 -0
- package/workflows/powers/flutter-feature/SKILL.md +62 -0
- package/workflows/powers/flutter-feature/references/architecture-rules.md +85 -0
- package/workflows/powers/flutter-feature/references/composite-provider.md +58 -0
- package/workflows/powers/flutter-feature/references/outbox-pattern.md +87 -0
- package/workflows/powers/flutter-feature/references/testing-patterns.md +218 -0
- package/workflows/powers/flutter-go-router/POWER.md +64 -0
- package/workflows/powers/flutter-go-router/SKILL.md +61 -0
- package/workflows/powers/flutter-go-router/references/guards-and-deeplinks.md +20 -0
- package/workflows/powers/flutter-go-router/references/typed-routes.md +27 -0
- package/workflows/powers/flutter-offline-sync/POWER.md +62 -0
- package/workflows/powers/flutter-offline-sync/SKILL.md +59 -0
- package/workflows/powers/flutter-offline-sync/references/outbox-full.md +44 -0
- package/workflows/powers/flutter-repository/POWER.md +64 -0
- package/workflows/powers/flutter-repository/SKILL.md +61 -0
- package/workflows/powers/flutter-repository/references/drift-patterns.md +21 -0
- package/workflows/powers/flutter-repository/references/retrofit-patterns.md +20 -0
- package/workflows/powers/flutter-riverpod/POWER.md +70 -0
- package/workflows/powers/flutter-riverpod/SKILL.md +67 -0
- package/workflows/powers/flutter-riverpod/references/async-and-mutations.md +19 -0
- package/workflows/powers/flutter-riverpod/references/async-lifecycle.md +19 -0
- package/workflows/powers/flutter-riverpod/references/provider-selection.md +20 -0
- package/workflows/powers/flutter-riverpod/references/testing.md +21 -0
- package/workflows/powers/flutter-riverpod/references/version-matrix.md +24 -0
- package/workflows/powers/flutter-state-machine/POWER.md +62 -0
- package/workflows/powers/flutter-state-machine/SKILL.md +59 -0
- package/workflows/powers/flutter-state-machine/references/app-state-contract.md +23 -0
- package/workflows/powers/flutter-state-machine/references/ui-rendering.md +14 -0
- package/workflows/powers/flutter-testing/POWER.md +64 -0
- package/workflows/powers/flutter-testing/SKILL.md +61 -0
- package/workflows/powers/flutter-testing/references/offline-sync-tests.md +16 -0
- package/workflows/powers/flutter-testing/references/test-layers.md +33 -0
- package/workflows/powers/frontend-code-review/POWER.md +137 -0
- package/workflows/powers/frontend-code-review/SKILL.md +134 -0
- package/workflows/powers/frontend-code-review/references/common-antipatterns.md +86 -0
- package/workflows/powers/frontend-code-review/references/performance-budgets.md +56 -0
- package/workflows/powers/frontend-code-review/references/review-checklists.md +47 -0
- package/workflows/powers/frontend-design/POWER.md +163 -362
- package/workflows/powers/frontend-design/SKILL.md +163 -362
- package/workflows/powers/game-development/POWER.md +57 -140
- package/workflows/powers/game-development/SKILL.md +57 -140
- package/workflows/powers/geo-fundamentals/POWER.md +64 -126
- package/workflows/powers/geo-fundamentals/SKILL.md +64 -127
- package/workflows/powers/git-workflow/POWER.md +135 -0
- package/workflows/powers/git-workflow/SKILL.md +132 -0
- package/workflows/powers/git-workflow/references/pr-review-checklist.md +63 -0
- package/workflows/powers/golang-pro/POWER.md +46 -35
- package/workflows/powers/golang-pro/SKILL.md +46 -35
- package/workflows/powers/graphql-architect/POWER.md +44 -62
- package/workflows/powers/graphql-architect/SKILL.md +44 -62
- package/workflows/powers/i18n-localization/POWER.md +118 -103
- package/workflows/powers/i18n-localization/SKILL.md +118 -103
- package/workflows/powers/java-pro/POWER.md +47 -22
- package/workflows/powers/java-pro/SKILL.md +47 -22
- package/workflows/powers/javascript-pro/POWER.md +47 -34
- package/workflows/powers/javascript-pro/SKILL.md +47 -34
- package/workflows/powers/kotlin-pro/POWER.md +46 -23
- package/workflows/powers/kotlin-pro/SKILL.md +46 -23
- package/workflows/powers/legacy-modernizer/POWER.md +43 -60
- package/workflows/powers/legacy-modernizer/SKILL.md +43 -60
- package/workflows/powers/mcp-builder/POWER.md +65 -0
- package/workflows/powers/mcp-builder/SKILL.md +62 -0
- package/workflows/powers/mcp-builder/references/testing-and-evals.md +17 -0
- package/workflows/powers/mcp-builder/references/transport-and-tool-design.md +17 -0
- package/workflows/powers/microservices-architect/POWER.md +43 -70
- package/workflows/powers/microservices-architect/SKILL.md +43 -70
- package/workflows/powers/mobile-design/POWER.md +110 -345
- package/workflows/powers/mobile-design/SKILL.md +110 -345
- package/workflows/powers/mongodb/POWER.md +67 -0
- package/workflows/powers/mongodb/SKILL.md +64 -0
- package/workflows/powers/mongodb/references/mongodb-checklist.md +20 -0
- package/workflows/powers/mysql/POWER.md +67 -0
- package/workflows/powers/mysql/SKILL.md +64 -0
- package/workflows/powers/mysql/references/mysql-checklist.md +20 -0
- package/workflows/powers/neki/POWER.md +67 -0
- package/workflows/powers/neki/SKILL.md +64 -0
- package/workflows/powers/neki/references/neki-checklist.md +18 -0
- package/workflows/powers/nestjs-expert/POWER.md +45 -91
- package/workflows/powers/nestjs-expert/SKILL.md +45 -91
- package/workflows/powers/nextjs-developer/POWER.md +51 -44
- package/workflows/powers/nextjs-developer/SKILL.md +51 -44
- package/workflows/powers/nodejs-best-practices/POWER.md +48 -29
- package/workflows/powers/nodejs-best-practices/SKILL.md +48 -29
- package/workflows/powers/observability/POWER.md +109 -0
- package/workflows/powers/observability/SKILL.md +106 -0
- package/workflows/powers/observability/references/alerting-and-slo-checklist.md +87 -0
- package/workflows/powers/observability/references/opentelemetry-setup-guide.md +121 -0
- package/workflows/powers/openai-docs/POWER.md +61 -0
- package/workflows/powers/openai-docs/SKILL.md +58 -0
- package/workflows/powers/openai-docs/references/official-source-playbook.md +10 -0
- package/workflows/powers/performance-profiling/POWER.md +61 -114
- package/workflows/powers/performance-profiling/SKILL.md +61 -114
- package/workflows/powers/php-pro/POWER.md +116 -0
- package/workflows/powers/php-pro/SKILL.md +113 -0
- package/workflows/powers/php-pro/references/architecture-and-di.md +239 -0
- package/workflows/powers/php-pro/references/modern-php-features.md +189 -0
- package/workflows/powers/php-pro/references/performance-and-deployment.md +197 -0
- package/workflows/powers/php-pro/references/php84-strict-typing-checklist.md +161 -0
- package/workflows/powers/php-pro/references/testing-and-static-analysis.md +235 -0
- package/workflows/powers/playwright-e2e/POWER.md +85 -0
- package/workflows/powers/playwright-e2e/SKILL.md +82 -0
- package/workflows/powers/playwright-e2e/references/locator-trace-flake-checklist.md +80 -0
- package/workflows/powers/postgres/POWER.md +67 -0
- package/workflows/powers/postgres/SKILL.md +64 -0
- package/workflows/powers/postgres/references/postgres-checklist.md +20 -0
- package/workflows/powers/prompt-engineer/POWER.md +47 -30
- package/workflows/powers/prompt-engineer/SKILL.md +47 -30
- package/workflows/powers/python-pro/POWER.md +47 -36
- package/workflows/powers/python-pro/SKILL.md +47 -36
- package/workflows/powers/react-best-practices/POWER.md +56 -33
- package/workflows/powers/react-best-practices/SKILL.md +56 -33
- package/workflows/powers/react-expert/POWER.md +47 -37
- package/workflows/powers/react-expert/SKILL.md +47 -37
- package/workflows/powers/redis/POWER.md +67 -0
- package/workflows/powers/redis/SKILL.md +64 -0
- package/workflows/powers/redis/references/redis-checklist.md +19 -0
- package/workflows/powers/ruby-pro/POWER.md +118 -0
- package/workflows/powers/ruby-pro/SKILL.md +115 -0
- package/workflows/powers/ruby-pro/references/modern-ruby-features.md +189 -0
- package/workflows/powers/ruby-pro/references/object-design-patterns.md +220 -0
- package/workflows/powers/ruby-pro/references/performance-and-profiling.md +224 -0
- package/workflows/powers/ruby-pro/references/ruby-concurrency-and-testing.md +190 -0
- package/workflows/powers/ruby-pro/references/testing-and-rspec.md +236 -0
- package/workflows/powers/rust-pro/POWER.md +45 -31
- package/workflows/powers/rust-pro/SKILL.md +45 -31
- package/workflows/powers/security-engineer/POWER.md +129 -0
- package/workflows/powers/security-engineer/SKILL.md +126 -0
- package/workflows/powers/seo-fundamentals/POWER.md +59 -102
- package/workflows/powers/seo-fundamentals/SKILL.md +59 -102
- package/workflows/powers/serverless-patterns/POWER.md +171 -0
- package/workflows/powers/serverless-patterns/SKILL.md +168 -0
- package/workflows/powers/skill-creator/POWER.md +90 -0
- package/workflows/powers/skill-creator/SKILL.md +87 -0
- package/workflows/powers/skill-creator/references/platform-formats.md +181 -0
- package/workflows/powers/skill-creator/references/schemas.md +430 -0
- package/workflows/powers/spec-miner/POWER.md +49 -57
- package/workflows/powers/spec-miner/SKILL.md +49 -57
- package/workflows/powers/sqlite/POWER.md +67 -0
- package/workflows/powers/sqlite/SKILL.md +64 -0
- package/workflows/powers/sqlite/references/sqlite-checklist.md +19 -0
- package/workflows/powers/sre-engineer/POWER.md +123 -64
- package/workflows/powers/sre-engineer/SKILL.md +123 -64
- package/workflows/powers/static-analysis/POWER.md +121 -77
- package/workflows/powers/static-analysis/SKILL.md +121 -77
- package/workflows/powers/stripe-best-practices/POWER.md +140 -17
- package/workflows/powers/stripe-best-practices/SKILL.md +139 -17
- package/workflows/powers/supabase/POWER.md +67 -0
- package/workflows/powers/supabase/SKILL.md +64 -0
- package/workflows/powers/supabase/references/supabase-checklist.md +19 -0
- package/workflows/powers/swift-pro/POWER.md +118 -0
- package/workflows/powers/swift-pro/SKILL.md +115 -0
- package/workflows/powers/swift-pro/references/concurrency-patterns.md +165 -0
- package/workflows/powers/swift-pro/references/protocol-and-generics.md +172 -0
- package/workflows/powers/swift-pro/references/sendable-and-isolation.md +116 -0
- package/workflows/powers/swift-pro/references/swift-concurrency-and-protocols.md +260 -0
- package/workflows/powers/swift-pro/references/testing-and-packages.md +192 -0
- package/workflows/powers/tailwind-patterns/POWER.md +71 -240
- package/workflows/powers/tailwind-patterns/SKILL.md +71 -240
- package/workflows/powers/testing-patterns/POWER.md +155 -10
- package/workflows/powers/testing-patterns/SKILL.md +155 -10
- package/workflows/powers/typescript-pro/POWER.md +47 -38
- package/workflows/powers/typescript-pro/SKILL.md +47 -38
- package/workflows/powers/vitess/POWER.md +67 -0
- package/workflows/powers/vitess/SKILL.md +64 -0
- package/workflows/powers/vitess/references/vitess-checklist.md +19 -0
- package/workflows/powers/vulnerability-scanner/POWER.md +146 -10
- package/workflows/powers/vulnerability-scanner/SKILL.md +146 -10
- package/workflows/powers/web-perf/POWER.md +43 -170
- package/workflows/powers/web-perf/SKILL.md +43 -170
- package/workflows/powers/webapp-testing/POWER.md +43 -164
- package/workflows/powers/webapp-testing/SKILL.md +43 -164
- package/workflows/skills/agent-design/SKILL.md +198 -0
- package/workflows/skills/agent-design/references/clarification-patterns.md +153 -0
- package/workflows/skills/agent-design/references/skill-testing.md +164 -0
- package/workflows/skills/agent-design/references/workflow-patterns.md +226 -0
- package/workflows/skills/deep-research/SKILL.md +25 -20
- package/workflows/skills/deep-research/references/multi-round-research-loop.md +73 -8
- package/workflows/skills/frontend-design/SKILL.md +37 -32
- package/workflows/skills/frontend-design/commands/brand.md +167 -0
- package/workflows/skills/frontend-design/references/brand-presets.md +228 -0
- package/workflows/skills/generated/skill-audit.json +11 -2
- package/workflows/skills/generated/skill-catalog.json +37 -5
- package/workflows/skills/skills_index.json +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/claude/skills/agent-design/SKILL.md +198 -0
- package/workflows/workflows/agent-environment-setup/platforms/claude/skills/agent-design/references/clarification-patterns.md +153 -0
- package/workflows/workflows/agent-environment-setup/platforms/claude/skills/agent-design/references/skill-testing.md +164 -0
- package/workflows/workflows/agent-environment-setup/platforms/claude/skills/agent-design/references/workflow-patterns.md +226 -0
- package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/SKILL.md +25 -20
- package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/references/multi-round-research-loop.md +73 -8
- package/workflows/workflows/agent-environment-setup/platforms/claude/skills/frontend-design/SKILL.md +37 -32
- package/workflows/workflows/agent-environment-setup/platforms/claude/skills/frontend-design/commands/brand.md +167 -0
- package/workflows/workflows/agent-environment-setup/platforms/claude/skills/frontend-design/references/brand-presets.md +228 -0
- package/workflows/workflows/agent-environment-setup/platforms/claude/skills/skills_index.json +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/agent-design/SKILL.md +197 -0
- package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/agent-design/references/clarification-patterns.md +153 -0
- package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/agent-design/references/skill-testing.md +164 -0
- package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/agent-design/references/workflow-patterns.md +226 -0
- package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/SKILL.md +25 -20
- package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/references/multi-round-research-loop.md +73 -8
- package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/frontend-design/SKILL.md +37 -32
- package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/frontend-design/commands/brand.md +167 -0
- package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/frontend-design/references/brand-presets.md +228 -0
- package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/skills_index.json +1 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
````markdown
|
|
2
|
+
---
|
|
3
|
+
inclusion: manual
|
|
4
|
+
name: flutter-drift
|
|
5
|
+
description: "Use when implementing or refactoring Flutter local persistence with Drift: tables, DAOs, typed queries, indexes, transactions, and migrations. Do not use for simple key-value storage or remote-only networking work."
|
|
6
|
+
license: MIT
|
|
7
|
+
metadata:
|
|
8
|
+
author: cubis-foundry
|
|
9
|
+
version: "1.0"
|
|
10
|
+
compatibility: Claude Code, Codex, GitHub Copilot
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Flutter Drift
|
|
14
|
+
|
|
15
|
+
## Purpose
|
|
16
|
+
|
|
17
|
+
Guide project-local SQLite persistence through Drift while keeping persistence
|
|
18
|
+
details in the data layer and repositories above the DAO boundary.
|
|
19
|
+
|
|
20
|
+
## When to Use
|
|
21
|
+
|
|
22
|
+
- Adding a new table or DAO
|
|
23
|
+
- Changing schema or indexes
|
|
24
|
+
- Writing a migration
|
|
25
|
+
- Adding typed multi-table queries
|
|
26
|
+
- Wiring repositories to local persistence
|
|
27
|
+
|
|
28
|
+
## Instructions
|
|
29
|
+
|
|
30
|
+
1. Define or update the table schema first.
|
|
31
|
+
2. Add indexes only for real filter, join, or sort paths.
|
|
32
|
+
3. Keep DAOs typed and persistence-focused.
|
|
33
|
+
4. Expose Drift through repositories instead of letting UI code call DAOs directly.
|
|
34
|
+
5. Use transactions for multi-table consistency.
|
|
35
|
+
6. Use explicit schema version bumps and migration steps for every persisted change.
|
|
36
|
+
7. Never drop or rewrite user data silently.
|
|
37
|
+
8. Test migration behavior from at least the previous production schema.
|
|
38
|
+
|
|
39
|
+
## Output Format
|
|
40
|
+
|
|
41
|
+
Produce Drift guidance or code that:
|
|
42
|
+
|
|
43
|
+
- keeps one app database entrypoint,
|
|
44
|
+
- uses typed DAOs and query helpers,
|
|
45
|
+
- explains index or migration choices when they matter,
|
|
46
|
+
- includes migration-test expectations for schema changes.
|
|
47
|
+
|
|
48
|
+
## References
|
|
49
|
+
|
|
50
|
+
Load only what the current step needs.
|
|
51
|
+
|
|
52
|
+
| File | Load when |
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| `references/migrations.md` | Changing schema version, adding columns or tables, or planning upgrade safety. |
|
|
55
|
+
| `references/query-patterns.md` | Designing tables, indexes, DAOs, joins, transactions, or repository integration. |
|
|
56
|
+
|
|
57
|
+
## Scripts
|
|
58
|
+
|
|
59
|
+
No helper scripts are required for this skill right now.
|
|
60
|
+
|
|
61
|
+
## Examples
|
|
62
|
+
|
|
63
|
+
- "Add a Drift table and DAO for offline product notes."
|
|
64
|
+
- "Plan a safe migration for a new required column in this Flutter database."
|
|
65
|
+
````
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flutter-drift
|
|
3
|
+
description: "Use when implementing or refactoring Flutter local persistence with Drift: tables, DAOs, typed queries, indexes, transactions, and migrations. Do not use for simple key-value storage or remote-only networking work."
|
|
4
|
+
license: MIT
|
|
5
|
+
metadata:
|
|
6
|
+
author: cubis-foundry
|
|
7
|
+
version: "1.0"
|
|
8
|
+
compatibility: Claude Code, Codex, GitHub Copilot
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Flutter Drift
|
|
12
|
+
|
|
13
|
+
## Purpose
|
|
14
|
+
|
|
15
|
+
Guide project-local SQLite persistence through Drift while keeping persistence
|
|
16
|
+
details in the data layer and repositories above the DAO boundary.
|
|
17
|
+
|
|
18
|
+
## When to Use
|
|
19
|
+
|
|
20
|
+
- Adding a new table or DAO
|
|
21
|
+
- Changing schema or indexes
|
|
22
|
+
- Writing a migration
|
|
23
|
+
- Adding typed multi-table queries
|
|
24
|
+
- Wiring repositories to local persistence
|
|
25
|
+
|
|
26
|
+
## Instructions
|
|
27
|
+
|
|
28
|
+
1. Define or update the table schema first.
|
|
29
|
+
2. Add indexes only for real filter, join, or sort paths.
|
|
30
|
+
3. Keep DAOs typed and persistence-focused.
|
|
31
|
+
4. Expose Drift through repositories instead of letting UI code call DAOs directly.
|
|
32
|
+
5. Use transactions for multi-table consistency.
|
|
33
|
+
6. Use explicit schema version bumps and migration steps for every persisted change.
|
|
34
|
+
7. Never drop or rewrite user data silently.
|
|
35
|
+
8. Test migration behavior from at least the previous production schema.
|
|
36
|
+
|
|
37
|
+
## Output Format
|
|
38
|
+
|
|
39
|
+
Produce Drift guidance or code that:
|
|
40
|
+
|
|
41
|
+
- keeps one app database entrypoint,
|
|
42
|
+
- uses typed DAOs and query helpers,
|
|
43
|
+
- explains index or migration choices when they matter,
|
|
44
|
+
- includes migration-test expectations for schema changes.
|
|
45
|
+
|
|
46
|
+
## References
|
|
47
|
+
|
|
48
|
+
Load only what the current step needs.
|
|
49
|
+
|
|
50
|
+
| File | Load when |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| `references/migrations.md` | Changing schema version, adding columns or tables, or planning upgrade safety. |
|
|
53
|
+
| `references/query-patterns.md` | Designing tables, indexes, DAOs, joins, transactions, or repository integration. |
|
|
54
|
+
|
|
55
|
+
## Scripts
|
|
56
|
+
|
|
57
|
+
No helper scripts are required for this skill right now.
|
|
58
|
+
|
|
59
|
+
## Examples
|
|
60
|
+
|
|
61
|
+
- "Add a Drift table and DAO for offline product notes."
|
|
62
|
+
- "Plan a safe migration for a new required column in this Flutter database."
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Migrations
|
|
2
|
+
|
|
3
|
+
## Migration Rules
|
|
4
|
+
|
|
5
|
+
- Increment `schemaVersion` every time persisted structure changes.
|
|
6
|
+
- Use `onCreate` for first-install setup only.
|
|
7
|
+
- Use `onUpgrade` for stepwise migrations from older versions.
|
|
8
|
+
- Backfill new required columns safely with defaults or staged rollout.
|
|
9
|
+
- Enable pragmas such as foreign keys intentionally in `beforeOpen`.
|
|
10
|
+
|
|
11
|
+
## Safe Upgrade Checklist
|
|
12
|
+
|
|
13
|
+
- Existing rows stay readable after upgrade.
|
|
14
|
+
- New nullable columns start nullable unless a safe default exists.
|
|
15
|
+
- New indexes are created during migration or through `createAll` only when safe.
|
|
16
|
+
- Data transforms are deterministic and reversible enough for debugging.
|
|
17
|
+
|
|
18
|
+
## Tests
|
|
19
|
+
|
|
20
|
+
- Test opening a fresh database.
|
|
21
|
+
- Test upgrading from the last production schema.
|
|
22
|
+
- Test representative old data through the upgrade path.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Query Patterns
|
|
2
|
+
|
|
3
|
+
## Table Design
|
|
4
|
+
|
|
5
|
+
- Use stable IDs with clear ownership rules.
|
|
6
|
+
- Add indexes for foreign keys, frequent filters, and common sort columns.
|
|
7
|
+
- Keep sync-related columns explicit when offline behavior exists.
|
|
8
|
+
|
|
9
|
+
## DAO Design
|
|
10
|
+
|
|
11
|
+
- Expose streams for UI-facing reactive reads.
|
|
12
|
+
- Expose one-shot reads for detail fetches or background work.
|
|
13
|
+
- Keep write methods small and composable.
|
|
14
|
+
- Return typed data or typed companions, not maps.
|
|
15
|
+
|
|
16
|
+
## Repository Integration
|
|
17
|
+
|
|
18
|
+
- Read flow: local-first, then optional remote refresh.
|
|
19
|
+
- Write flow: persist locally first, then reconcile sync policy.
|
|
20
|
+
- Mapper code belongs in the data layer, not in widgets.
|
|
21
|
+
|
|
22
|
+
## Use Raw SQL Only When
|
|
23
|
+
|
|
24
|
+
- a partial index or special SQLite feature needs it,
|
|
25
|
+
- a complex query is materially clearer in SQL,
|
|
26
|
+
- Drift's typed API cannot express the operation cleanly.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
````markdown
|
|
2
|
+
---
|
|
3
|
+
inclusion: manual
|
|
4
|
+
name: flutter-feature
|
|
5
|
+
description: "Use when scaffolding a full Flutter feature across data, domain, presentation, routing, offline sync, and tests. Do not use for isolated single-layer work when a narrower Flutter skill already fits."
|
|
6
|
+
license: MIT
|
|
7
|
+
metadata:
|
|
8
|
+
author: cubis-foundry
|
|
9
|
+
version: "1.0"
|
|
10
|
+
compatibility: Claude Code, Codex, GitHub Copilot
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Flutter Feature Scaffold
|
|
14
|
+
|
|
15
|
+
## Purpose
|
|
16
|
+
|
|
17
|
+
Generate a complete, architecture-compliant Flutter feature instead of shipping
|
|
18
|
+
partial stubs across disconnected layers.
|
|
19
|
+
|
|
20
|
+
## When to Use
|
|
21
|
+
|
|
22
|
+
- Adding a new feature with UI, state, data, and tests
|
|
23
|
+
- Scaffolding a feature that spans multiple layers
|
|
24
|
+
- Defining a feature that needs routing or offline support
|
|
25
|
+
- Generating a consistent feature folder structure
|
|
26
|
+
|
|
27
|
+
## Instructions
|
|
28
|
+
|
|
29
|
+
1. Clarify or infer the feature name, data fields, operations, cross-feature dependencies, business-logic needs, and offline conflict strategy.
|
|
30
|
+
2. Stop and resolve missing requirements before generating files.
|
|
31
|
+
3. Keep naming and folder structure consistent across data, domain, presentation, routing, and tests.
|
|
32
|
+
4. Add a domain service only when business rules justify it.
|
|
33
|
+
5. Add composite providers only when a screen composes multiple features.
|
|
34
|
+
6. Keep repository, service, notifier, and widget responsibilities separate.
|
|
35
|
+
7. Ship tests with the feature instead of leaving verification for later.
|
|
36
|
+
|
|
37
|
+
## Output Format
|
|
38
|
+
|
|
39
|
+
Produce feature scaffolding guidance or code that:
|
|
40
|
+
|
|
41
|
+
- names the expected files and layer ownership,
|
|
42
|
+
- calls out optional pieces such as domain services or composite providers,
|
|
43
|
+
- keeps offline writes on the outbox path when needed,
|
|
44
|
+
- includes the test surface that should ship with the feature.
|
|
45
|
+
|
|
46
|
+
## References
|
|
47
|
+
|
|
48
|
+
Load only what the current step needs.
|
|
49
|
+
|
|
50
|
+
| File | Load when |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| `references/architecture-rules.md` | Checking layer boundaries, naming, app-state rules, and design-system constraints. |
|
|
53
|
+
| `references/composite-provider.md` | A screen depends on multiple features and needs provider-layer composition. |
|
|
54
|
+
| `references/testing-patterns.md` | Generating repository, service, notifier, or widget tests. |
|
|
55
|
+
| `references/outbox-pattern.md` | The feature writes offline, syncs later, or needs conflict or dead-letter behavior. |
|
|
56
|
+
|
|
57
|
+
## Scripts
|
|
58
|
+
|
|
59
|
+
No helper scripts are required for this skill right now.
|
|
60
|
+
|
|
61
|
+
## Examples
|
|
62
|
+
|
|
63
|
+
- "Scaffold a Flutter inventory feature with offline edits and tests."
|
|
64
|
+
- "Generate the full feature structure for a new sales module."
|
|
65
|
+
````
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flutter-feature
|
|
3
|
+
description: "Use when scaffolding a full Flutter feature across data, domain, presentation, routing, offline sync, and tests. Do not use for isolated single-layer work when a narrower Flutter skill already fits."
|
|
4
|
+
license: MIT
|
|
5
|
+
metadata:
|
|
6
|
+
author: cubis-foundry
|
|
7
|
+
version: "1.0"
|
|
8
|
+
compatibility: Claude Code, Codex, GitHub Copilot
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Flutter Feature Scaffold
|
|
12
|
+
|
|
13
|
+
## Purpose
|
|
14
|
+
|
|
15
|
+
Generate a complete, architecture-compliant Flutter feature instead of shipping
|
|
16
|
+
partial stubs across disconnected layers.
|
|
17
|
+
|
|
18
|
+
## When to Use
|
|
19
|
+
|
|
20
|
+
- Adding a new feature with UI, state, data, and tests
|
|
21
|
+
- Scaffolding a feature that spans multiple layers
|
|
22
|
+
- Defining a feature that needs routing or offline support
|
|
23
|
+
- Generating a consistent feature folder structure
|
|
24
|
+
|
|
25
|
+
## Instructions
|
|
26
|
+
|
|
27
|
+
1. Clarify or infer the feature name, data fields, operations, cross-feature dependencies, business-logic needs, and offline conflict strategy.
|
|
28
|
+
2. Stop and resolve missing requirements before generating files.
|
|
29
|
+
3. Keep naming and folder structure consistent across data, domain, presentation, routing, and tests.
|
|
30
|
+
4. Add a domain service only when business rules justify it.
|
|
31
|
+
5. Add composite providers only when a screen composes multiple features.
|
|
32
|
+
6. Keep repository, service, notifier, and widget responsibilities separate.
|
|
33
|
+
7. Ship tests with the feature instead of leaving verification for later.
|
|
34
|
+
|
|
35
|
+
## Output Format
|
|
36
|
+
|
|
37
|
+
Produce feature scaffolding guidance or code that:
|
|
38
|
+
|
|
39
|
+
- names the expected files and layer ownership,
|
|
40
|
+
- calls out optional pieces such as domain services or composite providers,
|
|
41
|
+
- keeps offline writes on the outbox path when needed,
|
|
42
|
+
- includes the test surface that should ship with the feature.
|
|
43
|
+
|
|
44
|
+
## References
|
|
45
|
+
|
|
46
|
+
Load only what the current step needs.
|
|
47
|
+
|
|
48
|
+
| File | Load when |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| `references/architecture-rules.md` | Checking layer boundaries, naming, app-state rules, and design-system constraints. |
|
|
51
|
+
| `references/composite-provider.md` | A screen depends on multiple features and needs provider-layer composition. |
|
|
52
|
+
| `references/testing-patterns.md` | Generating repository, service, notifier, or widget tests. |
|
|
53
|
+
| `references/outbox-pattern.md` | The feature writes offline, syncs later, or needs conflict or dead-letter behavior. |
|
|
54
|
+
|
|
55
|
+
## Scripts
|
|
56
|
+
|
|
57
|
+
No helper scripts are required for this skill right now.
|
|
58
|
+
|
|
59
|
+
## Examples
|
|
60
|
+
|
|
61
|
+
- "Scaffold a Flutter inventory feature with offline edits and tests."
|
|
62
|
+
- "Generate the full feature structure for a new sales module."
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Architecture Rules Reference
|
|
2
|
+
|
|
3
|
+
## Layer Boundaries (NEVER cross these)
|
|
4
|
+
- Repository knows: Drift DAO + Retrofit API + OutboxService. Nothing else.
|
|
5
|
+
- Service knows: repositories and other services. Zero Flutter, zero Riverpod.
|
|
6
|
+
- Notifier knows: providers, services. Calls service/repo. Updates AppState.
|
|
7
|
+
- Widget knows: notifier. Renders AppState. Calls notifier methods.
|
|
8
|
+
- Cross-feature data: compose at the Riverpod provider layer ONLY (never repo→repo imports).
|
|
9
|
+
|
|
10
|
+
## File Rules
|
|
11
|
+
- One public class per file. Filename = class name in snake_case.
|
|
12
|
+
- Private helpers used only by that class may colocate.
|
|
13
|
+
- Extension methods on the class may colocate.
|
|
14
|
+
- If a helper is used by 2+ classes → give it its own file.
|
|
15
|
+
|
|
16
|
+
## Naming
|
|
17
|
+
- Files: `<feature>_<suffix>.dart` (e.g. `product_repository.dart`)
|
|
18
|
+
- Classes: `<Feature><Suffix>` (e.g. `ProductRepository`)
|
|
19
|
+
- Provider variables: `<feature><Suffix>Provider` (e.g. `productRepositoryProvider`)
|
|
20
|
+
- All codegen annotations: `@riverpod` (lowercase) on provider functions and Notifier classes
|
|
21
|
+
|
|
22
|
+
## AppState<T> — All 5 cases must be handled
|
|
23
|
+
```dart
|
|
24
|
+
sealed class AppState<T> {
|
|
25
|
+
const factory AppState.loading() = _Loading;
|
|
26
|
+
const factory AppState.data(T value) = _Data;
|
|
27
|
+
const factory AppState.empty() = _Empty;
|
|
28
|
+
const factory AppState.error(AppError error) = _Error;
|
|
29
|
+
const factory AppState.deadLetter({required AppError error, required String requestId}) = _DeadLetter;
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## AppError — Every error must carry a requestId
|
|
34
|
+
```dart
|
|
35
|
+
sealed class AppError {
|
|
36
|
+
const factory AppError.client({required String requestId, required int statusCode, required String userMessage, String? developerMessage}) = ClientError;
|
|
37
|
+
const factory AppError.server({required String requestId, required int statusCode, required String userMessage}) = ServerError;
|
|
38
|
+
const factory AppError.network({required String requestId, required String userMessage, int retryCount}) = NetworkError;
|
|
39
|
+
const factory AppError.database({required String requestId, required String userMessage, required Object cause}) = DatabaseError;
|
|
40
|
+
const factory AppError.syncDead({required String requestId, required String feature, required String operation, required String userMessage, required List<String> errorLog}) = SyncDeadError;
|
|
41
|
+
const factory AppError.conflict({required String requestId, required String userMessage, required Map<String, dynamic> localData, required Map<String, dynamic> serverData}) = ConflictError;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Repository Write Pattern (always)
|
|
46
|
+
```dart
|
|
47
|
+
Future<T> create(CreateInput input) async {
|
|
48
|
+
final operationId = const Uuid().v4();
|
|
49
|
+
final local = await dao.insert(input.toCompanion(operationId));
|
|
50
|
+
await outbox.enqueue(operationId: operationId, feature: '<n>', operation: 'create', payload: input.toJson());
|
|
51
|
+
if (await connectivity.isOnline) outbox.drainNow().ignore();
|
|
52
|
+
return local;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Notifier Pattern (always thin)
|
|
57
|
+
```dart
|
|
58
|
+
@riverpod
|
|
59
|
+
class <N>Notifier extends _$<N>Notifier {
|
|
60
|
+
@override
|
|
61
|
+
AppState<List<T>> build() {
|
|
62
|
+
ref.listen(<n>StreamProvider, (_, next) {
|
|
63
|
+
next.when(
|
|
64
|
+
data: (items) => state = items.isEmpty ? const AppState.empty() : AppState.data(items),
|
|
65
|
+
loading: () => state = const AppState.loading(),
|
|
66
|
+
error: (e, _) => state = AppState.error(_mapError(e)),
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
return const AppState.loading();
|
|
70
|
+
}
|
|
71
|
+
AppError _mapError(Object e) => ref.read(errorHandlerProvider).map(e);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Design System — NEVER hardcode
|
|
76
|
+
- Colors: `AppColors.<name>` only
|
|
77
|
+
- Spacing: `AppSpacing.xs/sm/md/lg/xl/xxl` (4/8/16/24/32/48)
|
|
78
|
+
- Radius: `AppRadius.sm/md/lg/full`
|
|
79
|
+
- Text: `AppTypography.<style>` only
|
|
80
|
+
- SyncStatusBadge: required on any widget displaying a record with syncStatus
|
|
81
|
+
|
|
82
|
+
## Auth Storage Rules
|
|
83
|
+
- Access token + refresh token → `FlutterSecureStorage` only
|
|
84
|
+
- Non-sensitive (userId, locale, theme) → `SharedPreferences`
|
|
85
|
+
- NEVER store tokens in SharedPreferences
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Composite Provider Pattern
|
|
2
|
+
|
|
3
|
+
## The Rule
|
|
4
|
+
When a screen needs data from multiple features (e.g. product + category +
|
|
5
|
+
inventory), NEVER import one repository from another repository. Compose at
|
|
6
|
+
the Riverpod provider layer only.
|
|
7
|
+
|
|
8
|
+
## Pattern
|
|
9
|
+
```dart
|
|
10
|
+
// Result type — freezed sealed class
|
|
11
|
+
@freezed
|
|
12
|
+
class ProductDetailState with _$ProductDetailState {
|
|
13
|
+
const factory ProductDetailState({
|
|
14
|
+
required Product product,
|
|
15
|
+
required Category category,
|
|
16
|
+
required InventoryStock inventory,
|
|
17
|
+
}) = _ProductDetailState;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Composite provider — each repo stays independent
|
|
21
|
+
@riverpod
|
|
22
|
+
Future<ProductDetailState> productDetail(Ref ref, String productId) async {
|
|
23
|
+
final product = await ref.watch(productRepositoryProvider).getById(productId);
|
|
24
|
+
if (product == null) throw AppError.client(
|
|
25
|
+
requestId: const Uuid().v4(),
|
|
26
|
+
statusCode: 404,
|
|
27
|
+
userMessage: 'Product not found',
|
|
28
|
+
);
|
|
29
|
+
final category = await ref.watch(categoryRepositoryProvider).getById(product.categoryId);
|
|
30
|
+
final inventory = await ref.watch(inventoryRepositoryProvider).getByProduct(productId);
|
|
31
|
+
|
|
32
|
+
return ProductDetailState(
|
|
33
|
+
product: product,
|
|
34
|
+
category: category!,
|
|
35
|
+
inventory: inventory,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Test
|
|
41
|
+
```dart
|
|
42
|
+
test('composes all three repos', () async {
|
|
43
|
+
final container = ProviderContainer(overrides: [
|
|
44
|
+
productRepositoryProvider.overrideWith((_) => FakeProductRepository()),
|
|
45
|
+
categoryRepositoryProvider.overrideWith((_) => FakeCategoryRepository()),
|
|
46
|
+
inventoryRepositoryProvider.overrideWith((_) => FakeInventoryRepository()),
|
|
47
|
+
]);
|
|
48
|
+
final state = await container.read(productDetailProvider('p1').future);
|
|
49
|
+
expect(state.category.name, isNotEmpty);
|
|
50
|
+
expect(state.inventory, isNotNull);
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## When to use
|
|
55
|
+
- Screen needs data from 2+ features
|
|
56
|
+
- Provider function (not a Notifier) — it's read-only composition
|
|
57
|
+
- State type is a dedicated `<Feature>DetailState` freezed class
|
|
58
|
+
- File goes in: `features/<main-feature>/presentation/providers/<n>_detail_provider.dart`
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Outbox Pattern Reference
|
|
2
|
+
|
|
3
|
+
## The Rule
|
|
4
|
+
Every write = local Drift first → outbox enqueue → return immediately.
|
|
5
|
+
Never await the network before returning to UI.
|
|
6
|
+
|
|
7
|
+
## Outbox Table (in AppDatabase)
|
|
8
|
+
```dart
|
|
9
|
+
class OutboxTable extends Table {
|
|
10
|
+
IntColumn get id => integer().autoIncrement()();
|
|
11
|
+
TextColumn get operationId => text()(); // UUID v4 — dedup key for server
|
|
12
|
+
TextColumn get feature => text()(); // e.g. 'product', 'sale'
|
|
13
|
+
TextColumn get operation => text()(); // 'create' | 'update' | 'delete'
|
|
14
|
+
TextColumn get payload => text()(); // jsonEncode(input.toJson())
|
|
15
|
+
IntColumn get retryCount => integer().withDefault(const Constant(0))();
|
|
16
|
+
IntColumn get maxRetries => integer().withDefault(const Constant(3))();
|
|
17
|
+
TextColumn get status => text().withDefault(const Constant('pending'))();
|
|
18
|
+
// pending → processing → done | failed → dead
|
|
19
|
+
DateTimeColumn get createdAt => dateTime()();
|
|
20
|
+
DateTimeColumn get lastAttemptAt => dateTime().nullable()();
|
|
21
|
+
TextColumn get errorLog => text().nullable()();
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Repository Write Template
|
|
26
|
+
```dart
|
|
27
|
+
Future<T> create(Create<T>Input input) async {
|
|
28
|
+
final operationId = const Uuid().v4();
|
|
29
|
+
|
|
30
|
+
// 1. Write locally — always succeeds even offline
|
|
31
|
+
final local = await dao.insert(
|
|
32
|
+
input.toCompanion(operationId: operationId),
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
// 2. Queue for sync
|
|
36
|
+
await outbox.enqueue(
|
|
37
|
+
operationId: operationId,
|
|
38
|
+
feature: '<feature>',
|
|
39
|
+
operation: 'create',
|
|
40
|
+
payload: input.toJson(),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// 3. Try immediate sync if online (fire-and-forget)
|
|
44
|
+
if (await connectivity.isOnline) outbox.drainNow().ignore();
|
|
45
|
+
|
|
46
|
+
// 4. Return local result — UI never waits for server
|
|
47
|
+
return local;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Sync Status on Drift Table
|
|
52
|
+
Every table that participates in offline sync adds:
|
|
53
|
+
```dart
|
|
54
|
+
TextColumn get syncStatus => text()
|
|
55
|
+
.withDefault(const Constant('pendingSync'))();
|
|
56
|
+
// Values: pendingSync | synced | failed | dead | conflict
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Conflict Strategies
|
|
60
|
+
Declare per-feature in the repository or service:
|
|
61
|
+
```dart
|
|
62
|
+
static const conflictStrategy = ConflictStrategy.clientWins;
|
|
63
|
+
// clientWins — offline action wins (sales, POS)
|
|
64
|
+
// serverWins — server is truth (pricing, master data)
|
|
65
|
+
// lastWriteWins — compare updatedAt timestamps
|
|
66
|
+
// manualResolve — surface ConflictError to user (safety-critical)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## OutboxService (auto-drain on reconnect)
|
|
70
|
+
The outbox service watches connectivity and auto-drains:
|
|
71
|
+
```dart
|
|
72
|
+
@override
|
|
73
|
+
AppState<OutboxState> build() {
|
|
74
|
+
ref.listen(connectivityProvider, (_, next) {
|
|
75
|
+
if (next == ConnectivityStatus.online) drainNow();
|
|
76
|
+
});
|
|
77
|
+
return const AppState.idle();
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## SyncStatusBadge Usage
|
|
82
|
+
Show on any ListTile or Card that displays a record with syncStatus:
|
|
83
|
+
```dart
|
|
84
|
+
SyncStatusBadge(status: item.syncStatus)
|
|
85
|
+
// Renders: 🕐 grey (pendingSync) | ✅ green (synced)
|
|
86
|
+
// ⚠️ amber (failed) | ❌ red (dead) | ⚡ orange (conflict)
|
|
87
|
+
```
|