@polymorphism-tech/morph-spec 4.7.0 → 4.7.2
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/.morph/.morphversion +5 -0
- package/.morph/analytics/threads-log.jsonl +5 -0
- package/.morph/config/config.json +8 -0
- package/.morph/framework/agents.json +1815 -0
- package/.morph/framework/hooks/README.md +205 -0
- package/.morph/framework/hooks/claude-code/notification/approval-reminder.js +54 -0
- package/.morph/framework/hooks/claude-code/post-tool-use/dispatch.js +83 -0
- package/.morph/framework/hooks/claude-code/post-tool-use/handle-tool-failure.js +42 -0
- package/.morph/framework/hooks/claude-code/pre-compact/save-morph-context.js +61 -0
- package/.morph/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +71 -0
- package/.morph/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +58 -0
- package/.morph/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +64 -0
- package/.morph/framework/hooks/claude-code/session-start/inject-morph-context.js +94 -0
- package/.morph/framework/hooks/claude-code/statusline.py +538 -0
- package/.morph/framework/hooks/claude-code/statusline.sh +7 -0
- package/.morph/framework/hooks/claude-code/stop/validate-completion.js +88 -0
- package/.morph/framework/hooks/claude-code/user-prompt/enrich-prompt.js +91 -0
- package/.morph/framework/hooks/git/commit-msg/conventional-commits.sh +33 -0
- package/.morph/framework/hooks/git/pre-commit/agents.sh +25 -0
- package/.morph/framework/hooks/git/pre-commit/orchestrator.sh +64 -0
- package/.morph/framework/hooks/git/pre-commit/specs.sh +50 -0
- package/.morph/framework/hooks/git/pre-push/run-tests.sh +44 -0
- package/.morph/framework/hooks/shared/hook-response.js +45 -0
- package/.morph/framework/hooks/shared/phase-utils.js +129 -0
- package/.morph/framework/hooks/shared/state-reader.js +138 -0
- package/.morph/framework/hooks/shared/stdin-reader.js +26 -0
- package/.morph/framework/standards/STANDARDS.json +933 -0
- package/.morph/framework/standards/ai-agents/blazor-ui.md +364 -0
- package/.morph/framework/standards/ai-agents/production.md +415 -0
- package/.morph/framework/standards/ai-agents/setup.md +418 -0
- package/.morph/framework/standards/ai-agents/team-orchestration.md +479 -0
- package/.morph/framework/standards/ai-agents/workflows.md +354 -0
- package/.morph/framework/standards/architecture/ddd/aggregates.md +120 -0
- package/.morph/framework/standards/architecture/ddd/bounded-contexts.md +105 -0
- package/.morph/framework/standards/architecture/ddd/complexity-levels.md +108 -0
- package/.morph/framework/standards/architecture/ddd/entities.md +99 -0
- package/.morph/framework/standards/architecture/ddd/ubiquitous-language.md +58 -0
- package/.morph/framework/standards/architecture/ddd/value-objects.md +124 -0
- package/.morph/framework/standards/backend/api/minimal-api.md +494 -0
- package/.morph/framework/standards/backend/api/rest.md +492 -0
- package/.morph/framework/standards/backend/api/validation.md +88 -0
- package/.morph/framework/standards/backend/authentication/passkeys.md +428 -0
- package/.morph/framework/standards/backend/database/ef-core.md +199 -0
- package/.morph/framework/standards/backend/database/migrations.md +393 -0
- package/.morph/framework/standards/backend/database/postgresql/database.md +352 -0
- package/.morph/framework/standards/backend/database/repository-patterns.md +528 -0
- package/.morph/framework/standards/backend/database/vector-search-rag.md +541 -0
- package/.morph/framework/standards/backend/dotnet/async.md +366 -0
- package/.morph/framework/standards/backend/dotnet/core.md +117 -0
- package/.morph/framework/standards/backend/dotnet/di.md +439 -0
- package/.morph/framework/standards/backend/dotnet/program-cs-checklist.md +92 -0
- package/.morph/framework/standards/backend/integrations/asaas/asaas-api.md +216 -0
- package/.morph/framework/standards/backend/integrations/clerk/clerk-auth.md +290 -0
- package/.morph/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +350 -0
- package/.morph/framework/standards/backend/integrations/resend/resend-email.md +385 -0
- package/.morph/framework/standards/context/analytics.md +96 -0
- package/.morph/framework/standards/context/bundles.md +110 -0
- package/.morph/framework/standards/context/priming.md +78 -0
- package/.morph/framework/standards/core/architecture.md +185 -0
- package/.morph/framework/standards/core/coding.md +214 -0
- package/.morph/framework/standards/core/git-branching-strategy.md +403 -0
- package/.morph/framework/standards/core/git.md +185 -0
- package/.morph/framework/standards/core/testing.md +295 -0
- package/.morph/framework/standards/data/nosql/blob-storage.md +102 -0
- package/.morph/framework/standards/data/nosql/cache/redis.md +97 -0
- package/.morph/framework/standards/data/nosql/cosmos-db.md +118 -0
- package/.morph/framework/standards/data/vector-search/azure-ai-search.md +121 -0
- package/.morph/framework/standards/data/vector-search/rag-chunking.md +104 -0
- package/.morph/framework/standards/frontend/blazor/design-checklist.md +222 -0
- package/.morph/framework/standards/frontend/blazor/fluent-ui-setup.md +595 -0
- package/.morph/framework/standards/frontend/blazor/fluent-ui.md +137 -0
- package/.morph/framework/standards/frontend/blazor/html-conversion.md +184 -0
- package/.morph/framework/standards/frontend/blazor/lifecycle.md +195 -0
- package/.morph/framework/standards/frontend/blazor/pitfalls.md +198 -0
- package/.morph/framework/standards/frontend/blazor/state.md +191 -0
- package/.morph/framework/standards/frontend/design-system/animations.md +151 -0
- package/.morph/framework/standards/frontend/design-system/naming.md +64 -0
- package/.morph/framework/standards/frontend/nextjs/app-router.md +123 -0
- package/.morph/framework/standards/frontend/nextjs/components.md +132 -0
- package/.morph/framework/standards/frontend/nextjs/data-fetching.md +126 -0
- package/.morph/framework/standards/frontend/nextjs/forms.md +128 -0
- package/.morph/framework/standards/frontend/nextjs/naming-conventions.md +67 -0
- package/.morph/framework/standards/frontend/nextjs/nextjs-patterns.md +215 -0
- package/.morph/framework/standards/frontend/nextjs/project-structure.md +102 -0
- package/.morph/framework/standards/frontend/nextjs/state-management.md +72 -0
- package/.morph/framework/standards/frontend/nextjs/testing.md +111 -0
- package/.morph/framework/standards/infrastructure/azure/azure.md +624 -0
- package/.morph/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +422 -0
- package/.morph/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +516 -0
- package/.morph/framework/standards/infrastructure/azure/devops/local-development.md +520 -0
- package/.morph/framework/standards/infrastructure/azure/services/functions.md +486 -0
- package/.morph/framework/standards/infrastructure/azure/services/service-bus.md +459 -0
- package/.morph/framework/standards/infrastructure/azure/services/storage.md +407 -0
- package/.morph/framework/standards/infrastructure/docker/easypanel-deploy.md +196 -0
- package/.morph/framework/standards/infrastructure/supabase/mcp-setup.md +252 -0
- package/.morph/framework/standards/infrastructure/supabase/supabase-auth.md +176 -0
- package/.morph/framework/standards/infrastructure/supabase/supabase-pgvector.md +169 -0
- package/.morph/framework/standards/infrastructure/supabase/supabase-rls.md +184 -0
- package/.morph/framework/standards/infrastructure/supabase/supabase-storage.md +153 -0
- package/.morph/framework/standards/integration/api/graphql.md +91 -0
- package/.morph/framework/standards/integration/api/grpc.md +114 -0
- package/.morph/framework/standards/integration/api/rest-design.md +95 -0
- package/.morph/framework/standards/integration/event-driven/cqrs.md +101 -0
- package/.morph/framework/standards/integration/event-driven/event-sourcing.md +124 -0
- package/.morph/framework/standards/integration/event-driven/service-bus.md +95 -0
- package/.morph/framework/standards/integration/mcp/mcp-tools.md +384 -0
- package/.morph/framework/standards/observability/logging.md +131 -0
- package/.morph/framework/standards/observability/metrics.md +121 -0
- package/.morph/framework/standards/observability/monitoring.md +114 -0
- package/.morph/framework/standards/observability/tracing.md +132 -0
- package/.morph/framework/standards/workflows/parallel-execution.md +112 -0
- package/.morph/framework/standards/workflows/thread-management.md +113 -0
- package/.morph/framework/templates/.idea/morph-templates.xml +92 -0
- package/.morph/framework/templates/.vscode/morph-templates.code-snippets +186 -0
- package/.morph/framework/templates/IDE-SNIPPETS.md +266 -0
- package/.morph/framework/templates/README.md +814 -0
- package/.morph/framework/templates/REGISTRY.json +1888 -0
- package/.morph/framework/templates/code/dotnet/backend/repository.cs +141 -0
- package/.morph/framework/templates/code/dotnet/backend/service.cs +139 -0
- package/.morph/framework/templates/code/dotnet/contracts/Commands.cs +74 -0
- package/.morph/framework/templates/code/dotnet/contracts/Entities.cs +25 -0
- package/.morph/framework/templates/code/dotnet/contracts/Queries.cs +74 -0
- package/.morph/framework/templates/code/dotnet/contracts/README.md +74 -0
- package/.morph/framework/templates/code/dotnet/contracts/api-contracts.cs +173 -0
- package/.morph/framework/templates/code/dotnet/contracts/contracts-level1.cs +69 -0
- package/.morph/framework/templates/code/dotnet/contracts/contracts-level2.cs +86 -0
- package/.morph/framework/templates/code/dotnet/contracts/contracts-level3.cs +41 -0
- package/.morph/framework/templates/code/dotnet/database/migration.cs +83 -0
- package/.morph/framework/templates/code/dotnet/frontend/component.razor +239 -0
- package/.morph/framework/templates/code/dotnet/jobs/agent.cs +163 -0
- package/.morph/framework/templates/code/dotnet/jobs/job.cs +171 -0
- package/.morph/framework/templates/code/dotnet/test.cs +239 -0
- package/.morph/framework/templates/code/sql/rls-policy.sql +57 -0
- package/.morph/framework/templates/code/sql/supabase-migration.sql +100 -0
- package/.morph/framework/templates/code/sql/supabase-migration.template.sql +113 -0
- package/.morph/framework/templates/code/typescript/contracts.ts +168 -0
- package/.morph/framework/templates/context/CONTEXT-FEATURE.md +276 -0
- package/.morph/framework/templates/context/CONTEXT.md +181 -0
- package/.morph/framework/templates/docs/clarifications.md +253 -0
- package/.morph/framework/templates/docs/onboarding.md +123 -0
- package/.morph/framework/templates/docs/proposal.md +182 -0
- package/.morph/framework/templates/docs/schema-analysis.md +119 -0
- package/.morph/framework/templates/docs/spec.md +198 -0
- package/.morph/framework/templates/docs/ui-components.md +124 -0
- package/.morph/framework/templates/docs/ui-design-system.md +76 -0
- package/.morph/framework/templates/docs/ui-flows.md +167 -0
- package/.morph/framework/templates/docs/ui-mockups.md +98 -0
- package/.morph/framework/templates/docs/user-stories.md +34 -0
- package/.morph/framework/templates/examples/design-system-examples.md +357 -0
- package/.morph/framework/templates/examples/spec-examples.md +90 -0
- package/.morph/framework/templates/feature/decisions.md +187 -0
- package/.morph/framework/templates/feature/recap.md +146 -0
- package/.morph/framework/templates/feature/tasks.md +199 -0
- package/.morph/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -0
- package/.morph/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -0
- package/.morph/framework/templates/frontend/nextjs/env.mjs.hbs +32 -0
- package/.morph/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -0
- package/.morph/framework/templates/frontend/nextjs/page.tsx.hbs +22 -0
- package/.morph/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -0
- package/.morph/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -0
- package/.morph/framework/templates/infrastructure/azure/Dockerfile.example +82 -0
- package/.morph/framework/templates/infrastructure/azure/README.md +286 -0
- package/.morph/framework/templates/infrastructure/azure/app-insights.bicep +63 -0
- package/.morph/framework/templates/infrastructure/azure/app-service.bicep +164 -0
- package/.morph/framework/templates/infrastructure/azure/container-app-env.bicep +49 -0
- package/.morph/framework/templates/infrastructure/azure/container-app.bicep +156 -0
- package/.morph/framework/templates/infrastructure/azure/deploy-checklist.md +426 -0
- package/.morph/framework/templates/infrastructure/azure/deploy.ps1 +229 -0
- package/.morph/framework/templates/infrastructure/azure/deploy.sh +208 -0
- package/.morph/framework/templates/infrastructure/azure/key-vault.bicep +91 -0
- package/.morph/framework/templates/infrastructure/azure/main.bicep +189 -0
- package/.morph/framework/templates/infrastructure/azure/parameters.dev.json +29 -0
- package/.morph/framework/templates/infrastructure/azure/parameters.prod.json +29 -0
- package/.morph/framework/templates/infrastructure/azure/parameters.staging.json +29 -0
- package/.morph/framework/templates/infrastructure/azure/sql-database.bicep +103 -0
- package/.morph/framework/templates/infrastructure/azure/storage.bicep +106 -0
- package/.morph/framework/templates/infrastructure/docker/Dockerfile.template +58 -0
- package/.morph/framework/templates/infrastructure/docker/docker-compose.template.yml +67 -0
- package/.morph/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -0
- package/.morph/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -0
- package/.morph/framework/templates/infrastructure/docker/easypanel.template.json +54 -0
- package/.morph/framework/templates/infrastructure/github/README.md +593 -0
- package/.morph/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +22 -0
- package/.morph/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -0
- package/.morph/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -0
- package/.morph/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +61 -0
- package/.morph/framework/templates/infrastructure/github/workflows/deploy-easypanel.yml.hbs +31 -0
- package/.morph/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -0
- package/.morph/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -0
- package/.morph/framework/templates/integrations/asaas-client.cs +387 -0
- package/.morph/framework/templates/integrations/asaas-webhook.cs +351 -0
- package/.morph/framework/templates/integrations/azure-identity-config.cs +288 -0
- package/.morph/framework/templates/integrations/clerk-config.cs +258 -0
- package/.morph/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -0
- package/.morph/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -0
- package/.morph/framework/templates/meta-prompts/hops/hop-retry.md +78 -0
- package/.morph/framework/templates/meta-prompts/hops/hop-validation.md +97 -0
- package/.morph/framework/templates/meta-prompts/hops/hop-wrapper.md +36 -0
- package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +113 -0
- package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +80 -0
- package/.morph/framework/templates/meta-prompts/squad-leaders/backend-squad.md +90 -0
- package/.morph/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +126 -0
- package/.morph/framework/templates/meta-prompts/squad-leaders/squad-leader.md +43 -0
- package/.morph/framework/templates/meta-prompts/validators/checkpoint-validator.md +107 -0
- package/.morph/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -0
- package/.morph/framework/templates/project-structure/dotnet-ddd.md +70 -0
- package/.morph/framework/templates/saas/subscription.cs +347 -0
- package/.morph/framework/templates/saas/tenant.cs +338 -0
- package/.morph/framework/templates/state.template.json +17 -0
- package/.morph/framework/templates/ui/FluentDesignTheme.cs +149 -0
- package/.morph/framework/templates/ui/MudTheme.cs +281 -0
- package/.morph/framework/templates/ui/design-system.css +226 -0
- package/.morph/logs/tool-failures.log +17 -0
- package/.morph/memory/pre-compact-2026-02-24T17-43-30-049Z.json +16 -0
- package/.morph/plans/eager-watching-bunny.md +105 -0
- package/.morph/plans/temporal-seeking-nebula.md +45 -0
- package/.morph/state.json +48 -0
- package/CLAUDE.md +1 -1
- package/README.md +119 -99
- package/bin/morph-spec.js +0 -9
- package/framework/CLAUDE.md +1 -1
- package/framework/hooks/README.md +10 -6
- package/framework/hooks/claude-code/notification/approval-reminder.js +2 -0
- package/framework/hooks/claude-code/post-tool-use/dispatch.js +1 -1
- package/framework/hooks/claude-code/stop/validate-completion.js +1 -1
- package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +1 -1
- package/package.json +1 -1
- package/src/commands/project/init.js +15 -42
- package/src/commands/project/update.js +22 -37
- package/src/lib/installers/mcp-installer.js +18 -3
- package/src/utils/hooks-installer.js +5 -15
- package/src/commands/project/detect.js +0 -114
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Spec Template Reference
|
|
2
|
+
|
|
3
|
+
> **Layer:** 3 | **Load:** on-demand | **Keywords:** spec, specification, template
|
|
4
|
+
|
|
5
|
+
**Use the stack's `.morph/framework/templates/spec.md` as the canonical template.**
|
|
6
|
+
|
|
7
|
+
This file contains extended examples for each spec section.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Example: Entity (Pseudo-code)
|
|
12
|
+
|
|
13
|
+
```csharp
|
|
14
|
+
class ProcessingJob {
|
|
15
|
+
Guid Id
|
|
16
|
+
string OriginalPhotoUrl // Azure Blob URL, max 500 chars
|
|
17
|
+
string? ProcessedPhotoUrl // Nullable, populated after processing
|
|
18
|
+
ProcessingStatus Status // Enum: Pending, Processing, Completed, Failed
|
|
19
|
+
DateTime CreatedAt
|
|
20
|
+
ICollection<ExecutionLog> Logs // 1:N relationship
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
enum ProcessingStatus {
|
|
24
|
+
Pending = 0, Processing = 1, Completed = 2, // Normal flow
|
|
25
|
+
Failed = 100 // Error states (high values)
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Example: Command (Pseudo-code)
|
|
30
|
+
|
|
31
|
+
```csharp
|
|
32
|
+
UploadPhotoCommand {
|
|
33
|
+
Input: IFormFile photo, string? email
|
|
34
|
+
Output: Guid jobId
|
|
35
|
+
|
|
36
|
+
Handler:
|
|
37
|
+
1. Validate file (size <= 10MB, type in [.jpg, .png])
|
|
38
|
+
2. Upload to Azure Blob Storage
|
|
39
|
+
3. Create ProcessingJob entity (status = Pending)
|
|
40
|
+
4. Enqueue Hangfire background job
|
|
41
|
+
5. Return jobId
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Example: API Endpoints
|
|
46
|
+
|
|
47
|
+
```csharp
|
|
48
|
+
PhotoProcessingController {
|
|
49
|
+
POST /api/upload → multipart/form-data → { jobId: Guid }
|
|
50
|
+
GET /api/status/{id} → jobId → { status, progress, createdAt }
|
|
51
|
+
GET /api/download/{id} → jobId → Redirect to Blob URL or 404
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Example: Flow
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
Upload Flow (Actor: User)
|
|
59
|
+
1. User selects photo → System validates (size, type) → If invalid: show error
|
|
60
|
+
2. User sees preview → clicks "Upload"
|
|
61
|
+
3. System creates ProcessingJob → uploads to Blob → enqueues Hangfire job → returns jobId
|
|
62
|
+
4. System navigates to /processing/{jobId} → polls every 5s
|
|
63
|
+
End State: User on progress page, job processing in background
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Example: ADR
|
|
67
|
+
|
|
68
|
+
### ADR-001: Use Hangfire for Background Jobs
|
|
69
|
+
**Status:** Accepted
|
|
70
|
+
**Context:** Need background processing for AI photo transformation (30-120s).
|
|
71
|
+
**Decision:** Hangfire (self-hosted).
|
|
72
|
+
**Alternatives:**
|
|
73
|
+
1. Azure Functions — serverless, auto-scaling, but cold start + $10/mo for 50k jobs
|
|
74
|
+
2. Hangfire — zero cost, simpler, but scales with app
|
|
75
|
+
3. Quartz.NET — more features, but steeper learning curve
|
|
76
|
+
**Trade-offs:** Simplicity vs Features (Hangfire sufficient for MVP)
|
|
77
|
+
|
|
78
|
+
## Example: Cost Estimate
|
|
79
|
+
|
|
80
|
+
| Resource | SKU | Monthly | Justification |
|
|
81
|
+
|----------|-----|---------|---------------|
|
|
82
|
+
| Blob Storage | LRS | $0.02 | Store photos, low redundancy OK |
|
|
83
|
+
| Azure SQL | Basic | $4.99 | < 100k jobs/month |
|
|
84
|
+
| Container App | Consumption | $0.49 | Scale to zero |
|
|
85
|
+
| Hangfire | Self-hosted | $0.00 | In-process |
|
|
86
|
+
| **Total** | | **~$5.50** | |
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
*MORPH-SPEC by Polymorphism Tech*
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Architecture Decision Records - {{titleCase FEATURE_NAME}}
|
|
2
|
+
|
|
3
|
+
## ADR-001: {Decision Title}
|
|
4
|
+
|
|
5
|
+
**Date:** {{DATE}}
|
|
6
|
+
**Status:** Proposed | Accepted | Deprecated | Superseded
|
|
7
|
+
**Deciders:** MORPH Agents, Developer
|
|
8
|
+
|
|
9
|
+
### Context
|
|
10
|
+
|
|
11
|
+
{Describe the context and problem that led to this decision}
|
|
12
|
+
|
|
13
|
+
### Decision
|
|
14
|
+
|
|
15
|
+
{Describe the decision made}
|
|
16
|
+
|
|
17
|
+
### Consequences
|
|
18
|
+
|
|
19
|
+
**Pros:**
|
|
20
|
+
- {Positive consequence 1}
|
|
21
|
+
- {Positive consequence 2}
|
|
22
|
+
|
|
23
|
+
**Cons:**
|
|
24
|
+
- {Negative consequence 1}
|
|
25
|
+
|
|
26
|
+
**Risks:**
|
|
27
|
+
- {Identified risk}
|
|
28
|
+
|
|
29
|
+
### Alternatives Considered
|
|
30
|
+
|
|
31
|
+
#### Option A: {Name}
|
|
32
|
+
- Pros: {advantages}
|
|
33
|
+
- Cons: {disadvantages}
|
|
34
|
+
- **Rejected because:** {reason}
|
|
35
|
+
|
|
36
|
+
#### Option B: {Name}
|
|
37
|
+
- Pros: {advantages}
|
|
38
|
+
- Cons: {disadvantages}
|
|
39
|
+
- **Rejected because:** {reason}
|
|
40
|
+
|
|
41
|
+
{{#if (eq STACK "blazor-azure")}}
|
|
42
|
+
### Affected Flows
|
|
43
|
+
- **Main flow:** {ex: Upload -> Payment -> Generation -> Email}
|
|
44
|
+
- **Alternative flow:** {ex: Upload -> Generation -> Payment -> Email}
|
|
45
|
+
- **Free flow:** {ex: Upload -> Generation -> Download}
|
|
46
|
+
|
|
47
|
+
### Impacted State Validations
|
|
48
|
+
|
|
49
|
+
> **Reference:** `framework/standards/status-validation.md`
|
|
50
|
+
|
|
51
|
+
| Service | Method | Accepted States |
|
|
52
|
+
|---------|--------|-----------------|
|
|
53
|
+
| {ServiceName} | {MethodName} | {ex: PendingPayment, Completed} |
|
|
54
|
+
|
|
55
|
+
### UI Components with Special Behavior
|
|
56
|
+
- {ex: FluentDialog requires initial Hidden="true"}
|
|
57
|
+
- {ex: Modal needs @ref for programmatic control}
|
|
58
|
+
{{/if}}
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
{{#if (eq STACK "blazor-azure")}}
|
|
63
|
+
## ADR-002: Database Model
|
|
64
|
+
|
|
65
|
+
**Date:** {{DATE}}
|
|
66
|
+
**Status:** Accepted
|
|
67
|
+
|
|
68
|
+
### Context
|
|
69
|
+
|
|
70
|
+
Need to define how {Feature} data will be stored.
|
|
71
|
+
|
|
72
|
+
### Decision
|
|
73
|
+
|
|
74
|
+
Use Azure SQL with the following model:
|
|
75
|
+
- {Entity} table with {columns}
|
|
76
|
+
- JSON columns for {flexible data}
|
|
77
|
+
|
|
78
|
+
### Consequences
|
|
79
|
+
|
|
80
|
+
**Pros:**
|
|
81
|
+
- Fits within free tier (32GB)
|
|
82
|
+
- Good query performance
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## ADR-003: AI Integration
|
|
87
|
+
|
|
88
|
+
**Date:** {{DATE}}
|
|
89
|
+
**Status:** Accepted
|
|
90
|
+
|
|
91
|
+
### Context
|
|
92
|
+
|
|
93
|
+
Feature requires AI capabilities for {purpose}.
|
|
94
|
+
|
|
95
|
+
### Decision
|
|
96
|
+
|
|
97
|
+
Use MS Agent Framework with gpt-4o-mini model.
|
|
98
|
+
|
|
99
|
+
### Consequences
|
|
100
|
+
|
|
101
|
+
**Pros:**
|
|
102
|
+
- Cost effective (~$0.15/1M input tokens)
|
|
103
|
+
- Good enough quality for this use case
|
|
104
|
+
|
|
105
|
+
**Cons:**
|
|
106
|
+
- Slightly less capable than gpt-4o
|
|
107
|
+
{{/if}}
|
|
108
|
+
|
|
109
|
+
{{#if (eq STACK "nextjs-supabase")}}
|
|
110
|
+
## ADR-002: Database Access Strategy
|
|
111
|
+
|
|
112
|
+
**Date:** {{DATE}}
|
|
113
|
+
**Status:** Accepted
|
|
114
|
+
|
|
115
|
+
### Context
|
|
116
|
+
|
|
117
|
+
Need to decide how the .NET API accesses Supabase PostgreSQL.
|
|
118
|
+
|
|
119
|
+
### Decision
|
|
120
|
+
|
|
121
|
+
Use Dapper with Npgsql for direct SQL queries. No EF Core.
|
|
122
|
+
|
|
123
|
+
### Consequences
|
|
124
|
+
|
|
125
|
+
**Pros:**
|
|
126
|
+
- Full control over SQL queries
|
|
127
|
+
- Better performance (no ORM overhead)
|
|
128
|
+
- Direct access to PostgreSQL features (jsonb, pgvector, functions)
|
|
129
|
+
- RLS policies apply naturally through connection
|
|
130
|
+
|
|
131
|
+
**Cons:**
|
|
132
|
+
- No automatic migrations (use Supabase CLI instead)
|
|
133
|
+
- Manual SQL query writing
|
|
134
|
+
- No change tracking
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## ADR-003: Auth Strategy
|
|
139
|
+
|
|
140
|
+
**Date:** {{DATE}}
|
|
141
|
+
**Status:** Accepted
|
|
142
|
+
|
|
143
|
+
### Context
|
|
144
|
+
|
|
145
|
+
Need authentication for both Next.js frontend and .NET API.
|
|
146
|
+
|
|
147
|
+
### Decision
|
|
148
|
+
|
|
149
|
+
Use Supabase Auth with @supabase/ssr on frontend. Validate JWT tokens in .NET API middleware.
|
|
150
|
+
|
|
151
|
+
### Consequences
|
|
152
|
+
|
|
153
|
+
**Pros:**
|
|
154
|
+
- Single auth provider for both layers
|
|
155
|
+
- RLS policies work automatically with auth.uid()
|
|
156
|
+
- Built-in social login, magic links, email/password
|
|
157
|
+
- No separate auth service to maintain
|
|
158
|
+
|
|
159
|
+
**Cons:**
|
|
160
|
+
- Coupled to Supabase ecosystem
|
|
161
|
+
- JWT secret must be shared with .NET API
|
|
162
|
+
{{/if}}
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Template for New ADRs
|
|
167
|
+
|
|
168
|
+
```markdown
|
|
169
|
+
## ADR-XXX: {Title}
|
|
170
|
+
|
|
171
|
+
**Date:**
|
|
172
|
+
**Status:** Proposed | Accepted | Deprecated | Superseded
|
|
173
|
+
|
|
174
|
+
### Context
|
|
175
|
+
{Why is this decision needed?}
|
|
176
|
+
|
|
177
|
+
### Decision
|
|
178
|
+
{What was decided?}
|
|
179
|
+
|
|
180
|
+
### Consequences
|
|
181
|
+
**Pros:** {list}
|
|
182
|
+
**Cons:** {list}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
*Generated by MORPH Framework*
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Feature Recap: {{titleCase FEATURE_NAME}}
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
| Field | Value |
|
|
6
|
+
|-------|-------|
|
|
7
|
+
| **Feature ID** | {{FEATURE_NAME}} |
|
|
8
|
+
| **Completed** | {{DATE}} |
|
|
9
|
+
| **Total Tasks** | {X} |
|
|
10
|
+
| **Time Spent** | {X}h |
|
|
11
|
+
| **Agents Used** | {list} |
|
|
12
|
+
{{#if STACK}}| **Stack** | {{STACK}} |{{/if}}
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Tasks Completed
|
|
17
|
+
|
|
18
|
+
| ID | Title | Category | Duration |
|
|
19
|
+
|----|-------|----------|----------|
|
|
20
|
+
| T001 | {title} | {{#if (eq STACK "nextjs-supabase")}}Database{{else}}{category}{{/if}} | {X}min |
|
|
21
|
+
| T002 | {title} | {{#if (eq STACK "nextjs-supabase")}}Backend{{else}}{category}{{/if}} | {X}min |
|
|
22
|
+
| T003 | {title} | {{#if (eq STACK "nextjs-supabase")}}Frontend{{else}}{category}{{/if}} | {X}min |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
{{#if (eq STACK "nextjs-supabase")}}
|
|
27
|
+
## Validation Results
|
|
28
|
+
|
|
29
|
+
| Validator | Status | Details |
|
|
30
|
+
|-----------|--------|---------|
|
|
31
|
+
| contract-compliance | Pass/Fail | {details} |
|
|
32
|
+
| architecture | Pass/Fail | {details} |
|
|
33
|
+
| design-system | Pass/Fail | {details} |
|
|
34
|
+
| coding-standards | Pass/Fail | {details} |
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
{{/if}}
|
|
39
|
+
## What Was Delivered
|
|
40
|
+
|
|
41
|
+
### Functionality
|
|
42
|
+
- {Functionality 1 delivered}
|
|
43
|
+
- {Functionality 2 delivered}
|
|
44
|
+
- {Functionality 3 delivered}
|
|
45
|
+
|
|
46
|
+
{{#if (eq STACK "nextjs-supabase")}}
|
|
47
|
+
### Database (Supabase)
|
|
48
|
+
- Tables: {list}
|
|
49
|
+
- RLS Policies: {count} policies
|
|
50
|
+
- Migrations: {count} files
|
|
51
|
+
|
|
52
|
+
### Backend API (.NET)
|
|
53
|
+
- Endpoints: {count} endpoints
|
|
54
|
+
- Services: {list}
|
|
55
|
+
|
|
56
|
+
### Frontend (Next.js)
|
|
57
|
+
- Pages: {list}
|
|
58
|
+
- Components: {list}
|
|
59
|
+
{{/if}}
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Files Created
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
{{#if (eq STACK "nextjs-supabase")}}
|
|
67
|
+
supabase/migrations/{files}
|
|
68
|
+
backend/src/{files}
|
|
69
|
+
frontend/src/{files}
|
|
70
|
+
{{else}}
|
|
71
|
+
{list of created files}
|
|
72
|
+
{{/if}}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Files Modified
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
{list of modified files}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Architecture Decisions
|
|
84
|
+
|
|
85
|
+
| Decision | Rationale |
|
|
86
|
+
|----------|-----------|
|
|
87
|
+
| {Decision 1} | {Reason} |
|
|
88
|
+
| {Decision 2} | {Reason} |
|
|
89
|
+
|
|
90
|
+
See full ADRs in `decisions.md`
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Test Coverage
|
|
95
|
+
|
|
96
|
+
| Type | Files | Coverage |
|
|
97
|
+
|------|-------|----------|
|
|
98
|
+
| {{#if (eq STACK "nextjs-supabase")}}Backend Unit{{else}}Unit Tests{{/if}} | {X} | {X}% |
|
|
99
|
+
| {{#if (eq STACK "nextjs-supabase")}}Frontend Component{{else}}Integration Tests{{/if}} | {X} | {X}% |
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Lessons Learned
|
|
104
|
+
|
|
105
|
+
### What Went Well
|
|
106
|
+
- {Positive point 1}
|
|
107
|
+
- {Positive point 2}
|
|
108
|
+
|
|
109
|
+
### What Could Be Improved
|
|
110
|
+
- {Improvement point 1}
|
|
111
|
+
- {Improvement point 2}
|
|
112
|
+
|
|
113
|
+
### Recommendations for Future
|
|
114
|
+
- {Recommendation 1}
|
|
115
|
+
- {Recommendation 2}
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Metrics
|
|
120
|
+
|
|
121
|
+
| Metric | Value |
|
|
122
|
+
|--------|-------|
|
|
123
|
+
| Tasks Completed | {X}/{X} |
|
|
124
|
+
| Checkpoints Passed | {X} |
|
|
125
|
+
{{#if (eq STACK "nextjs-supabase")}}| Validation Passes | {X}/{X} |
|
|
126
|
+
{{else}}| Code Reviews | {X} |
|
|
127
|
+
{{/if}}| Bugs Found | {X} |
|
|
128
|
+
| Bugs Fixed | {X} |
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Related Resources
|
|
133
|
+
|
|
134
|
+
- **Proposal:** `proposal.md`
|
|
135
|
+
- **Spec:** `spec.md`
|
|
136
|
+
{{#if (eq STACK "nextjs-supabase")}}- **Contracts (.NET):** `contracts.cs`
|
|
137
|
+
- **Contracts (TS):** `contracts.ts`
|
|
138
|
+
{{else}}- **Contracts:** `contracts.cs`
|
|
139
|
+
{{/if}}- **Tasks:** `tasks.md`
|
|
140
|
+
- **Decisions:** `decisions.md`
|
|
141
|
+
{{#if (eq STACK "blazor-azure")}}- **Azure DevOps Epic:** {link}
|
|
142
|
+
{{/if}}- **PR:** {link}
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
*Generated by MORPH Framework on {{DATE}}*
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# Tasks - {{titleCase FEATURE_NAME}}
|
|
2
|
+
|
|
3
|
+
> Implementation checklist for the feature.
|
|
4
|
+
> Update status as you progress.
|
|
5
|
+
|
|
6
|
+
| Task ID | Type | Title | Status |
|
|
7
|
+
|---------|------|-------|--------|
|
|
8
|
+
| T001 | {type} | {title} | Pending |
|
|
9
|
+
| T002 | {type} | {title} | Pending |
|
|
10
|
+
| T003 | {type} | {title} | In Progress |
|
|
11
|
+
| T004 | {type} | {title} | Blocked |
|
|
12
|
+
| T005 | {type} | {title} | Done |
|
|
13
|
+
|
|
14
|
+
**Status Values:** `Pending | In Progress | Blocked | Done`
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Task Granularity
|
|
19
|
+
|
|
20
|
+
### Ideal Task
|
|
21
|
+
- 15-60 minutes of implementation
|
|
22
|
+
- 1-5 files modified
|
|
23
|
+
- Testable in isolation
|
|
24
|
+
- Independent commit possible
|
|
25
|
+
|
|
26
|
+
### Signs of Too Broad (Split)
|
|
27
|
+
**Bad example:** "Implement feature"
|
|
28
|
+
**Split into:**
|
|
29
|
+
- T001: Define contracts and interfaces
|
|
30
|
+
- T002: Implement data layer
|
|
31
|
+
- T003: Implement business logic
|
|
32
|
+
- T004: Create UI components
|
|
33
|
+
- T005: Write tests
|
|
34
|
+
|
|
35
|
+
### Signs of Too Granular (Merge)
|
|
36
|
+
**Bad example:** "Create field A", "Create field B", "Create field C"
|
|
37
|
+
**Merge into:** "Create data model with all fields"
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Gates & Reviews
|
|
42
|
+
|
|
43
|
+
| Task ID | Type | Description | Status |
|
|
44
|
+
|---------|------|-------------|--------|
|
|
45
|
+
| T003 | Review | Review contracts and data model | Pending |
|
|
46
|
+
| T006 | Review | Review implementation | Pending |
|
|
47
|
+
| T009 | Approval | Approve UI before testing | Pending |
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Phase 1: Contracts & Data Model
|
|
52
|
+
|
|
53
|
+
### T001: Define contracts and interfaces
|
|
54
|
+
- **Type:** Contract
|
|
55
|
+
- **Priority:** 1
|
|
56
|
+
- **Estimate:** 30min
|
|
57
|
+
- **Assigned:** {agent}
|
|
58
|
+
- **Dependencies:** None
|
|
59
|
+
|
|
60
|
+
**Description:**
|
|
61
|
+
|
|
62
|
+
Define service interfaces and contracts.
|
|
63
|
+
|
|
64
|
+
**Deliverables:**
|
|
65
|
+
- [ ] Create: `{path-to-interface-file}`
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
### T002: Create data model
|
|
70
|
+
- **Type:** {{#if (eq STACK "nextjs-supabase")}}Database{{else}}Domain{{/if}}
|
|
71
|
+
- **Priority:** 1
|
|
72
|
+
- **Estimate:** 45min
|
|
73
|
+
- **Assigned:** {agent}
|
|
74
|
+
- **Dependencies:** None
|
|
75
|
+
|
|
76
|
+
**Description:**
|
|
77
|
+
|
|
78
|
+
Create data model {{#if (eq STACK "nextjs-supabase")}}with migrations{{else}}with entities{{/if}}.
|
|
79
|
+
|
|
80
|
+
**Deliverables:**
|
|
81
|
+
- [ ] Create: `{path-to-model-file}`
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Phase 2: Implementation
|
|
86
|
+
|
|
87
|
+
### T003: Implement data layer
|
|
88
|
+
- **Type:** {{#if (eq STACK "nextjs-supabase")}}Repository{{else}}Infrastructure{{/if}}
|
|
89
|
+
- **Priority:** 2
|
|
90
|
+
- **Estimate:** 1h
|
|
91
|
+
- **Assigned:** {agent}
|
|
92
|
+
- **Dependencies:** T001, T002
|
|
93
|
+
|
|
94
|
+
**Description:**
|
|
95
|
+
|
|
96
|
+
Implement data access layer.
|
|
97
|
+
|
|
98
|
+
**Deliverables:**
|
|
99
|
+
- [ ] Create: `{path-to-repository-file}`
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
### T004: Implement business logic
|
|
104
|
+
- **Type:** Service
|
|
105
|
+
- **Priority:** 2
|
|
106
|
+
- **Estimate:** 1h
|
|
107
|
+
- **Assigned:** {agent}
|
|
108
|
+
- **Dependencies:** T001, T003
|
|
109
|
+
|
|
110
|
+
**Description:**
|
|
111
|
+
|
|
112
|
+
Implement service layer with business logic.
|
|
113
|
+
|
|
114
|
+
**Deliverables:**
|
|
115
|
+
- [ ] Create: `{path-to-service-file}`
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Phase 3: UI Components
|
|
120
|
+
|
|
121
|
+
### T005: Create list component
|
|
122
|
+
- **Type:** UI
|
|
123
|
+
- **Priority:** 2
|
|
124
|
+
- **Estimate:** 45min
|
|
125
|
+
- **Assigned:** {agent}
|
|
126
|
+
- **Dependencies:** T004
|
|
127
|
+
|
|
128
|
+
**Description:**
|
|
129
|
+
|
|
130
|
+
Create component to list items.
|
|
131
|
+
|
|
132
|
+
**Deliverables:**
|
|
133
|
+
- [ ] Create: `{path-to-component-file}`
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### T006: Create form component
|
|
138
|
+
- **Type:** UI
|
|
139
|
+
- **Priority:** 2
|
|
140
|
+
- **Estimate:** 1h
|
|
141
|
+
- **Assigned:** {agent}
|
|
142
|
+
- **Dependencies:** T005
|
|
143
|
+
|
|
144
|
+
**Description:**
|
|
145
|
+
|
|
146
|
+
Create component for create/edit.
|
|
147
|
+
|
|
148
|
+
**Deliverables:**
|
|
149
|
+
- [ ] Create: `{path-to-form-file}`
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Phase 4: Testing
|
|
154
|
+
|
|
155
|
+
### T007: Write unit tests
|
|
156
|
+
- **Type:** Test
|
|
157
|
+
- **Priority:** 2
|
|
158
|
+
- **Estimate:** 1h
|
|
159
|
+
- **Assigned:** {agent}
|
|
160
|
+
- **Dependencies:** T004
|
|
161
|
+
|
|
162
|
+
**Description:**
|
|
163
|
+
|
|
164
|
+
Unit tests for service layer.
|
|
165
|
+
|
|
166
|
+
**Deliverables:**
|
|
167
|
+
- [ ] Create: `{path-to-test-file}`
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
### T008: Write integration tests
|
|
172
|
+
- **Type:** Test
|
|
173
|
+
- **Priority:** 3
|
|
174
|
+
- **Estimate:** 1h
|
|
175
|
+
- **Assigned:** {agent}
|
|
176
|
+
- **Dependencies:** T007
|
|
177
|
+
|
|
178
|
+
**Description:**
|
|
179
|
+
|
|
180
|
+
Integration tests for {{#if (eq STACK "nextjs-supabase")}}API and database{{else}}repository and API{{/if}}.
|
|
181
|
+
|
|
182
|
+
**Deliverables:**
|
|
183
|
+
- [ ] Create: `{path-to-integration-test-file}`
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Summary
|
|
188
|
+
|
|
189
|
+
| Phase | Tasks | Estimate |
|
|
190
|
+
|-------|-------|----------|
|
|
191
|
+
| Phase 1 | T001-T002 | {X}h |
|
|
192
|
+
| Phase 2 | T003-T004 | {X}h |
|
|
193
|
+
| Phase 3 | T005-T006 | {X}h |
|
|
194
|
+
| Phase 4 | T007-T008 | {X}h |
|
|
195
|
+
| **Total** | **8 tasks** | **{X}h** |
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
*Generated by MORPH Framework*
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Multi-stage Next.js production build for EasyPanel
|
|
2
|
+
# Stage 1: Dependencies
|
|
3
|
+
FROM node:20-alpine AS deps
|
|
4
|
+
RUN apk add --no-cache libc6-compat
|
|
5
|
+
WORKDIR /app
|
|
6
|
+
|
|
7
|
+
COPY package.json package-lock.json* ./
|
|
8
|
+
RUN npm ci --only=production && npm cache clean --force
|
|
9
|
+
|
|
10
|
+
# Stage 2: Build
|
|
11
|
+
FROM node:20-alpine AS builder
|
|
12
|
+
WORKDIR /app
|
|
13
|
+
|
|
14
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
15
|
+
COPY . .
|
|
16
|
+
|
|
17
|
+
# Build args for NEXT_PUBLIC_ variables (must be available at build time)
|
|
18
|
+
ARG NEXT_PUBLIC_APP_URL
|
|
19
|
+
ENV NEXT_PUBLIC_APP_URL=$NEXT_PUBLIC_APP_URL
|
|
20
|
+
|
|
21
|
+
RUN npm run build
|
|
22
|
+
|
|
23
|
+
# Stage 3: Production runner
|
|
24
|
+
FROM node:20-alpine AS runner
|
|
25
|
+
WORKDIR /app
|
|
26
|
+
|
|
27
|
+
ENV NODE_ENV=production
|
|
28
|
+
ENV NEXT_TELEMETRY_DISABLED=1
|
|
29
|
+
|
|
30
|
+
RUN addgroup --system --gid 1001 nodejs
|
|
31
|
+
RUN adduser --system --uid 1001 nextjs
|
|
32
|
+
|
|
33
|
+
COPY --from=builder /app/public ./public
|
|
34
|
+
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
|
35
|
+
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
|
36
|
+
|
|
37
|
+
USER nextjs
|
|
38
|
+
|
|
39
|
+
EXPOSE 3000
|
|
40
|
+
ENV PORT=3000
|
|
41
|
+
ENV HOSTNAME="0.0.0.0"
|
|
42
|
+
|
|
43
|
+
CMD ["node", "server.js"]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// features/{{kebabCase featureName}}/components/{{kebabCase featureName}}-list.tsx
|
|
2
|
+
'use client';
|
|
3
|
+
|
|
4
|
+
import { use{{pascalCase featureName}}s } from '@/features/{{kebabCase featureName}}/hooks/use-{{kebabCase featureName}}s';
|
|
5
|
+
import { DataTable } from '@/components/data-table';
|
|
6
|
+
import type { {{pascalCase featureName}} } from '@/features/{{kebabCase featureName}}/types/{{kebabCase featureName}}.types';
|
|
7
|
+
import type { ColumnDef } from '@tanstack/react-table';
|
|
8
|
+
|
|
9
|
+
const columns: ColumnDef<{{pascalCase featureName}}>[] = [
|
|
10
|
+
{ accessorKey: 'id', header: 'ID' },
|
|
11
|
+
{ accessorKey: 'name', header: 'Name' },
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
interface {{pascalCase featureName}}ListProps {
|
|
15
|
+
initialData?: {{pascalCase featureName}}[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function {{pascalCase featureName}}List({ initialData }: {{pascalCase featureName}}ListProps) {
|
|
19
|
+
const { data = initialData ?? [], isLoading } = use{{pascalCase featureName}}s();
|
|
20
|
+
|
|
21
|
+
if (isLoading) {
|
|
22
|
+
return <div className="flex items-center justify-center h-32">Loading...</div>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return <DataTable columns={columns} data={data} />;
|
|
26
|
+
}
|