Compare commits

...

16 Commits

Author SHA1 Message Date
e632a9d010 Add type casting for RichText data props with DefaultTypedEditorState 2025-10-14 00:38:32 +08:00
296c1ae0e4 Add type definition for introContent in ArchiveBlock component 2025-10-14 00:25:16 +08:00
b2df353533 Add type casting for post content in RichText component 2025-10-14 00:13:53 +08:00
8f64e99a49 Remove shared Tailwind config from backend
Remove the shared Tailwind configuration import and content array
integration from the backend's Tailwind config.
2025-10-13 23:54:06 +08:00
fdde6d8020 update pnpm-lock 2025-10-13 17:20:37 +08:00
093da91b58 update pnpm-lock 2025-10-13 16:35:42 +08:00
2d2c32657f fix tailwind shared config 2025-10-13 16:22:11 +08:00
6702d524f0 update payload latest version 2025-10-13 16:11:04 +08:00
d0d94799a4 update component.tsx 2025-10-13 15:26:16 +08:00
4678e47a8b update r2 config for enchunCMS email adapter 2025-10-13 15:10:02 +08:00
65c27e3386 add cloudflare R2 config 2025-10-13 11:37:20 +08:00
pukpuk
8e8ff0bfc7 chore: fix gitignore pattern to exclude build artifacts
Update .gitignore to properly ignore dist directories at any level by
changing /dist to **/dist pattern. Also remove previously tracked
.astro/types.d.ts file which should not be in version control.

- Fix: Change /dist to **/dist to match nested dist directories
- Remove: apps/frontend/.astro/types.d.ts from tracking
- Ensures build artifacts are properly excluded across the project

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-07 16:18:37 +08:00
6b0cb56046 chore: remove .DS_Store files from version control
Remove macOS-generated .DS_Store files that should not be tracked.
These files are already excluded in .gitignore.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-07 01:06:10 +08:00
c2d4c8d0a0 chore(workflow): add AI-assisted workflow commands and configurations
Add comprehensive workflow commands for AI-assisted development:
- Claude commands: analyze, clarify, plan
- Kilocode workflows: full feature development lifecycle
- Opencode commands: specification and implementation workflows
- Roo MCP configuration for tool integration

Update .gitignore to exclude .astro build cache directories.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-07 01:06:10 +08:00
pukpuk
cf0f779ad4 feat: introduce spec-workflow and upgrade frontend dependencies
This commit introduces the spec-workflow, a set of templates for creating design, product, requirements, and other specification documents. These templates are added to both the root directory and the `apps/frontend` workspace.

Additionally, this commit upgrades the frontend development dependencies for the Astro application. The key changes include:
- Migration from `@astrojs/tailwind` to `@tailwindcss/vite` for Tailwind CSS integration.
- Deletion of the `postcss.config.cjs` file, as it is no longer needed with the new setup.
- Updates to `astro.config.mjs` to use the new Vite plugin for Tailwind CSS.
- General upgrade of Astro and other related dependencies in `apps/frontend/package.json` and the corresponding `pnpm-lock.yaml` file.
2025-10-06 12:35:06 +08:00
7f61b58880 feat: support nested footer links 2025-09-29 21:19:48 +08:00
170 changed files with 43659 additions and 14110 deletions

BIN
.DS_Store vendored

Binary file not shown.

101
.claude/commands/analyze.md Normal file
View File

@@ -0,0 +1,101 @@
---
description: Perform a non-destructive cross-artifact consistency and quality analysis across spec.md, plan.md, and tasks.md after task generation.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
Goal: Identify inconsistencies, duplications, ambiguities, and underspecified items across the three core artifacts (`spec.md`, `plan.md`, `tasks.md`) before implementation. This command MUST run only after `/tasks` has successfully produced a complete `tasks.md`.
STRICTLY READ-ONLY: Do **not** modify any files. Output a structured analysis report. Offer an optional remediation plan (user must explicitly approve before any follow-up editing commands would be invoked manually).
Constitution Authority: The project constitution (`.specify/memory/constitution.md`) is **non-negotiable** within this analysis scope. Constitution conflicts are automatically CRITICAL and require adjustment of the spec, plan, or tasks—not dilution, reinterpretation, or silent ignoring of the principle. If a principle itself needs to change, that must occur in a separate, explicit constitution update outside `/analyze`.
Execution steps:
1. Run `.specify/scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks` once from repo root and parse JSON for FEATURE_DIR and AVAILABLE_DOCS. Derive absolute paths:
- SPEC = FEATURE_DIR/spec.md
- PLAN = FEATURE_DIR/plan.md
- TASKS = FEATURE_DIR/tasks.md
Abort with an error message if any required file is missing (instruct the user to run missing prerequisite command).
2. Load artifacts:
- Parse spec.md sections: Overview/Context, Functional Requirements, Non-Functional Requirements, User Stories, Edge Cases (if present).
- Parse plan.md: Architecture/stack choices, Data Model references, Phases, Technical constraints.
- Parse tasks.md: Task IDs, descriptions, phase grouping, parallel markers [P], referenced file paths.
- Load constitution `.specify/memory/constitution.md` for principle validation.
3. Build internal semantic models:
- Requirements inventory: Each functional + non-functional requirement with a stable key (derive slug based on imperative phrase; e.g., "User can upload file" -> `user-can-upload-file`).
- User story/action inventory.
- Task coverage mapping: Map each task to one or more requirements or stories (inference by keyword / explicit reference patterns like IDs or key phrases).
- Constitution rule set: Extract principle names and any MUST/SHOULD normative statements.
4. Detection passes:
A. Duplication detection:
- Identify near-duplicate requirements. Mark lower-quality phrasing for consolidation.
B. Ambiguity detection:
- Flag vague adjectives (fast, scalable, secure, intuitive, robust) lacking measurable criteria.
- Flag unresolved placeholders (TODO, TKTK, ???, <placeholder>, etc.).
C. Underspecification:
- Requirements with verbs but missing object or measurable outcome.
- User stories missing acceptance criteria alignment.
- Tasks referencing files or components not defined in spec/plan.
D. Constitution alignment:
- Any requirement or plan element conflicting with a MUST principle.
- Missing mandated sections or quality gates from constitution.
E. Coverage gaps:
- Requirements with zero associated tasks.
- Tasks with no mapped requirement/story.
- Non-functional requirements not reflected in tasks (e.g., performance, security).
F. Inconsistency:
- Terminology drift (same concept named differently across files).
- Data entities referenced in plan but absent in spec (or vice versa).
- Task ordering contradictions (e.g., integration tasks before foundational setup tasks without dependency note).
- Conflicting requirements (e.g., one requires to use Next.js while other says to use Vue as the framework).
5. Severity assignment heuristic:
- CRITICAL: Violates constitution MUST, missing core spec artifact, or requirement with zero coverage that blocks baseline functionality.
- HIGH: Duplicate or conflicting requirement, ambiguous security/performance attribute, untestable acceptance criterion.
- MEDIUM: Terminology drift, missing non-functional task coverage, underspecified edge case.
- LOW: Style/wording improvements, minor redundancy not affecting execution order.
6. Produce a Markdown report (no file writes) with sections:
### Specification Analysis Report
| ID | Category | Severity | Location(s) | Summary | Recommendation |
|----|----------|----------|-------------|---------|----------------|
| A1 | Duplication | HIGH | spec.md:L120-134 | Two similar requirements ... | Merge phrasing; keep clearer version |
(Add one row per finding; generate stable IDs prefixed by category initial.)
Additional subsections:
- Coverage Summary Table:
| Requirement Key | Has Task? | Task IDs | Notes |
- Constitution Alignment Issues (if any)
- Unmapped Tasks (if any)
- Metrics:
* Total Requirements
* Total Tasks
* Coverage % (requirements with >=1 task)
* Ambiguity Count
* Duplication Count
* Critical Issues Count
7. At end of report, output a concise Next Actions block:
- If CRITICAL issues exist: Recommend resolving before `/implement`.
- If only LOW/MEDIUM: User may proceed, but provide improvement suggestions.
- Provide explicit command suggestions: e.g., "Run /specify with refinement", "Run /plan to adjust architecture", "Manually edit tasks.md to add coverage for 'performance-metrics'".
8. Ask the user: "Would you like me to suggest concrete remediation edits for the top N issues?" (Do NOT apply them automatically.)
Behavior rules:
- NEVER modify files.
- NEVER hallucinate missing sections—if absent, report them.
- KEEP findings deterministic: if rerun without changes, produce consistent IDs and counts.
- LIMIT total findings in the main table to 50; aggregate remainder in a summarized overflow note.
- If zero issues found, emit a success report with coverage statistics and proceed recommendation.
Context: $ARGUMENTS

158
.claude/commands/clarify.md Normal file
View File

@@ -0,0 +1,158 @@
---
description: Identify underspecified areas in the current feature spec by asking up to 5 highly targeted clarification questions and encoding answers back into the spec.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
Goal: Detect and reduce ambiguity or missing decision points in the active feature specification and record the clarifications directly in the spec file.
Note: This clarification workflow is expected to run (and be completed) BEFORE invoking `/plan`. If the user explicitly states they are skipping clarification (e.g., exploratory spike), you may proceed, but must warn that downstream rework risk increases.
Execution steps:
1. Run `.specify/scripts/bash/check-prerequisites.sh --json --paths-only` from repo root **once** (combined `--json --paths-only` mode / `-Json -PathsOnly`). Parse minimal JSON payload fields:
- `FEATURE_DIR`
- `FEATURE_SPEC`
- (Optionally capture `IMPL_PLAN`, `TASKS` for future chained flows.)
- If JSON parsing fails, abort and instruct user to re-run `/specify` or verify feature branch environment.
2. Load the current spec file. Perform a structured ambiguity & coverage scan using this taxonomy. For each category, mark status: Clear / Partial / Missing. Produce an internal coverage map used for prioritization (do not output raw map unless no questions will be asked).
Functional Scope & Behavior:
- Core user goals & success criteria
- Explicit out-of-scope declarations
- User roles / personas differentiation
Domain & Data Model:
- Entities, attributes, relationships
- Identity & uniqueness rules
- Lifecycle/state transitions
- Data volume / scale assumptions
Interaction & UX Flow:
- Critical user journeys / sequences
- Error/empty/loading states
- Accessibility or localization notes
Non-Functional Quality Attributes:
- Performance (latency, throughput targets)
- Scalability (horizontal/vertical, limits)
- Reliability & availability (uptime, recovery expectations)
- Observability (logging, metrics, tracing signals)
- Security & privacy (authN/Z, data protection, threat assumptions)
- Compliance / regulatory constraints (if any)
Integration & External Dependencies:
- External services/APIs and failure modes
- Data import/export formats
- Protocol/versioning assumptions
Edge Cases & Failure Handling:
- Negative scenarios
- Rate limiting / throttling
- Conflict resolution (e.g., concurrent edits)
Constraints & Tradeoffs:
- Technical constraints (language, storage, hosting)
- Explicit tradeoffs or rejected alternatives
Terminology & Consistency:
- Canonical glossary terms
- Avoided synonyms / deprecated terms
Completion Signals:
- Acceptance criteria testability
- Measurable Definition of Done style indicators
Misc / Placeholders:
- TODO markers / unresolved decisions
- Ambiguous adjectives ("robust", "intuitive") lacking quantification
For each category with Partial or Missing status, add a candidate question opportunity unless:
- Clarification would not materially change implementation or validation strategy
- Information is better deferred to planning phase (note internally)
3. Generate (internally) a prioritized queue of candidate clarification questions (maximum 5). Do NOT output them all at once. Apply these constraints:
- Maximum of 5 total questions across the whole session.
- Each question must be answerable with EITHER:
* A short multiplechoice selection (25 distinct, mutually exclusive options), OR
* A one-word / shortphrase answer (explicitly constrain: "Answer in <=5 words").
- Only include questions whose answers materially impact architecture, data modeling, task decomposition, test design, UX behavior, operational readiness, or compliance validation.
- Ensure category coverage balance: attempt to cover the highest impact unresolved categories first; avoid asking two low-impact questions when a single high-impact area (e.g., security posture) is unresolved.
- Exclude questions already answered, trivial stylistic preferences, or plan-level execution details (unless blocking correctness).
- Favor clarifications that reduce downstream rework risk or prevent misaligned acceptance tests.
- If more than 5 categories remain unresolved, select the top 5 by (Impact * Uncertainty) heuristic.
4. Sequential questioning loop (interactive):
- Present EXACTLY ONE question at a time.
- For multiplechoice questions render options as a Markdown table:
| Option | Description |
|--------|-------------|
| A | <Option A description> |
| B | <Option B description> |
| C | <Option C description> | (add D/E as needed up to 5)
| Short | Provide a different short answer (<=5 words) | (Include only if free-form alternative is appropriate)
- For shortanswer style (no meaningful discrete options), output a single line after the question: `Format: Short answer (<=5 words)`.
- After the user answers:
* Validate the answer maps to one option or fits the <=5 word constraint.
* If ambiguous, ask for a quick disambiguation (count still belongs to same question; do not advance).
* Once satisfactory, record it in working memory (do not yet write to disk) and move to the next queued question.
- Stop asking further questions when:
* All critical ambiguities resolved early (remaining queued items become unnecessary), OR
* User signals completion ("done", "good", "no more"), OR
* You reach 5 asked questions.
- Never reveal future queued questions in advance.
- If no valid questions exist at start, immediately report no critical ambiguities.
5. Integration after EACH accepted answer (incremental update approach):
- Maintain in-memory representation of the spec (loaded once at start) plus the raw file contents.
- For the first integrated answer in this session:
* Ensure a `## Clarifications` section exists (create it just after the highest-level contextual/overview section per the spec template if missing).
* Under it, create (if not present) a `### Session YYYY-MM-DD` subheading for today.
- Append a bullet line immediately after acceptance: `- Q: <question> → A: <final answer>`.
- Then immediately apply the clarification to the most appropriate section(s):
* Functional ambiguity → Update or add a bullet in Functional Requirements.
* User interaction / actor distinction → Update User Stories or Actors subsection (if present) with clarified role, constraint, or scenario.
* Data shape / entities → Update Data Model (add fields, types, relationships) preserving ordering; note added constraints succinctly.
* Non-functional constraint → Add/modify measurable criteria in Non-Functional / Quality Attributes section (convert vague adjective to metric or explicit target).
* Edge case / negative flow → Add a new bullet under Edge Cases / Error Handling (or create such subsection if template provides placeholder for it).
* Terminology conflict → Normalize term across spec; retain original only if necessary by adding `(formerly referred to as "X")` once.
- If the clarification invalidates an earlier ambiguous statement, replace that statement instead of duplicating; leave no obsolete contradictory text.
- Save the spec file AFTER each integration to minimize risk of context loss (atomic overwrite).
- Preserve formatting: do not reorder unrelated sections; keep heading hierarchy intact.
- Keep each inserted clarification minimal and testable (avoid narrative drift).
6. Validation (performed after EACH write plus final pass):
- Clarifications session contains exactly one bullet per accepted answer (no duplicates).
- Total asked (accepted) questions ≤ 5.
- Updated sections contain no lingering vague placeholders the new answer was meant to resolve.
- No contradictory earlier statement remains (scan for now-invalid alternative choices removed).
- Markdown structure valid; only allowed new headings: `## Clarifications`, `### Session YYYY-MM-DD`.
- Terminology consistency: same canonical term used across all updated sections.
7. Write the updated spec back to `FEATURE_SPEC`.
8. Report completion (after questioning loop ends or early termination):
- Number of questions asked & answered.
- Path to updated spec.
- Sections touched (list names).
- Coverage summary table listing each taxonomy category with Status: Resolved (was Partial/Missing and addressed), Deferred (exceeds question quota or better suited for planning), Clear (already sufficient), Outstanding (still Partial/Missing but low impact).
- If any Outstanding or Deferred remain, recommend whether to proceed to `/plan` or run `/clarify` again later post-plan.
- Suggested next command.
Behavior rules:
- If no meaningful ambiguities found (or all potential questions would be low-impact), respond: "No critical ambiguities detected worth formal clarification." and suggest proceeding.
- If spec file missing, instruct user to run `/specify` first (do not create a new spec here).
- Never exceed 5 total asked questions (clarification retries for a single question do not count as new questions).
- Avoid speculative tech stack questions unless the absence blocks functional clarity.
- Respect user early termination signals ("stop", "done", "proceed").
- If no questions asked due to full coverage, output a compact coverage summary (all categories Clear) then suggest advancing.
- If quota reached with unresolved high-impact categories remaining, explicitly flag them under Deferred with rationale.
Context for prioritization: $ARGUMENTS

View File

@@ -11,6 +11,7 @@ $ARGUMENTS
Given the implementation details provided as an argument, do this: Given the implementation details provided as an argument, do this:
1. Run `.specify/scripts/bash/setup-plan.sh --json` from the repo root and parse JSON for FEATURE_SPEC, IMPL_PLAN, SPECS_DIR, BRANCH. All future file paths must be absolute. 1. Run `.specify/scripts/bash/setup-plan.sh --json` from the repo root and parse JSON for FEATURE_SPEC, IMPL_PLAN, SPECS_DIR, BRANCH. All future file paths must be absolute.
- BEFORE proceeding, inspect FEATURE_SPEC for a `## Clarifications` section with at least one `Session` subheading. If missing or clearly ambiguous areas remain (vague adjectives, unresolved critical choices), PAUSE and instruct the user to run `/clarify` first to reduce rework. Only continue if: (a) Clarifications exist OR (b) an explicit user override is provided (e.g., "proceed without clarification"). Do not attempt to fabricate clarifications yourself.
2. Read and analyze the feature specification to understand: 2. Read and analyze the feature specification to understand:
- The feature requirements and user stories - The feature requirements and user stories
- Functional and non-functional requirements - Functional and non-functional requirements

View File

@@ -11,6 +11,7 @@ $ARGUMENTS
Given the implementation details provided as an argument, do this: Given the implementation details provided as an argument, do this:
1. Run `.specify/scripts/bash/setup-plan.sh --json` from the repo root and parse JSON for FEATURE_SPEC, IMPL_PLAN, SPECS_DIR, BRANCH. All future file paths must be absolute. 1. Run `.specify/scripts/bash/setup-plan.sh --json` from the repo root and parse JSON for FEATURE_SPEC, IMPL_PLAN, SPECS_DIR, BRANCH. All future file paths must be absolute.
- BEFORE proceeding, inspect FEATURE_SPEC for a `## Clarifications` section with at least one `Session` subheading. If missing or clearly ambiguous areas remain (vague adjectives, unresolved critical choices), PAUSE and instruct the user to run `/clarify` first to reduce rework. Only continue if: (a) Clarifications exist OR (b) an explicit user override is provided (e.g., "proceed without clarification"). Do not attempt to fabricate clarifications yourself.
2. Read and analyze the feature specification to understand: 2. Read and analyze the feature specification to understand:
- The feature requirements and user stories - The feature requirements and user stories
- Functional and non-functional requirements - Functional and non-functional requirements

6
.gitignore vendored
View File

@@ -3,8 +3,9 @@
**/node_modules **/node_modules
# Build output # Build output
/dist **/dist
/build /build
**/.astro
# Logs # Logs
*.log *.log
@@ -41,3 +42,6 @@ Thumbs.db
# OS-generated files in subdirs # OS-generated files in subdirs
**/.DS_Store **/.DS_Store
# BMAD (local only)
.bmad-core/
.bmad-*/

View File

@@ -0,0 +1,101 @@
---
description: Perform a non-destructive cross-artifact consistency and quality analysis across spec.md, plan.md, and tasks.md after task generation.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
Goal: Identify inconsistencies, duplications, ambiguities, and underspecified items across the three core artifacts (`spec.md`, `plan.md`, `tasks.md`) before implementation. This command MUST run only after `/tasks` has successfully produced a complete `tasks.md`.
STRICTLY READ-ONLY: Do **not** modify any files. Output a structured analysis report. Offer an optional remediation plan (user must explicitly approve before any follow-up editing commands would be invoked manually).
Constitution Authority: The project constitution (`.specify/memory/constitution.md`) is **non-negotiable** within this analysis scope. Constitution conflicts are automatically CRITICAL and require adjustment of the spec, plan, or tasks—not dilution, reinterpretation, or silent ignoring of the principle. If a principle itself needs to change, that must occur in a separate, explicit constitution update outside `/analyze`.
Execution steps:
1. Run `.specify/scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks` once from repo root and parse JSON for FEATURE_DIR and AVAILABLE_DOCS. Derive absolute paths:
- SPEC = FEATURE_DIR/spec.md
- PLAN = FEATURE_DIR/plan.md
- TASKS = FEATURE_DIR/tasks.md
Abort with an error message if any required file is missing (instruct the user to run missing prerequisite command).
2. Load artifacts:
- Parse spec.md sections: Overview/Context, Functional Requirements, Non-Functional Requirements, User Stories, Edge Cases (if present).
- Parse plan.md: Architecture/stack choices, Data Model references, Phases, Technical constraints.
- Parse tasks.md: Task IDs, descriptions, phase grouping, parallel markers [P], referenced file paths.
- Load constitution `.specify/memory/constitution.md` for principle validation.
3. Build internal semantic models:
- Requirements inventory: Each functional + non-functional requirement with a stable key (derive slug based on imperative phrase; e.g., "User can upload file" -> `user-can-upload-file`).
- User story/action inventory.
- Task coverage mapping: Map each task to one or more requirements or stories (inference by keyword / explicit reference patterns like IDs or key phrases).
- Constitution rule set: Extract principle names and any MUST/SHOULD normative statements.
4. Detection passes:
A. Duplication detection:
- Identify near-duplicate requirements. Mark lower-quality phrasing for consolidation.
B. Ambiguity detection:
- Flag vague adjectives (fast, scalable, secure, intuitive, robust) lacking measurable criteria.
- Flag unresolved placeholders (TODO, TKTK, ???, <placeholder>, etc.).
C. Underspecification:
- Requirements with verbs but missing object or measurable outcome.
- User stories missing acceptance criteria alignment.
- Tasks referencing files or components not defined in spec/plan.
D. Constitution alignment:
- Any requirement or plan element conflicting with a MUST principle.
- Missing mandated sections or quality gates from constitution.
E. Coverage gaps:
- Requirements with zero associated tasks.
- Tasks with no mapped requirement/story.
- Non-functional requirements not reflected in tasks (e.g., performance, security).
F. Inconsistency:
- Terminology drift (same concept named differently across files).
- Data entities referenced in plan but absent in spec (or vice versa).
- Task ordering contradictions (e.g., integration tasks before foundational setup tasks without dependency note).
- Conflicting requirements (e.g., one requires to use Next.js while other says to use Vue as the framework).
5. Severity assignment heuristic:
- CRITICAL: Violates constitution MUST, missing core spec artifact, or requirement with zero coverage that blocks baseline functionality.
- HIGH: Duplicate or conflicting requirement, ambiguous security/performance attribute, untestable acceptance criterion.
- MEDIUM: Terminology drift, missing non-functional task coverage, underspecified edge case.
- LOW: Style/wording improvements, minor redundancy not affecting execution order.
6. Produce a Markdown report (no file writes) with sections:
### Specification Analysis Report
| ID | Category | Severity | Location(s) | Summary | Recommendation |
|----|----------|----------|-------------|---------|----------------|
| A1 | Duplication | HIGH | spec.md:L120-134 | Two similar requirements ... | Merge phrasing; keep clearer version |
(Add one row per finding; generate stable IDs prefixed by category initial.)
Additional subsections:
- Coverage Summary Table:
| Requirement Key | Has Task? | Task IDs | Notes |
- Constitution Alignment Issues (if any)
- Unmapped Tasks (if any)
- Metrics:
* Total Requirements
* Total Tasks
* Coverage % (requirements with >=1 task)
* Ambiguity Count
* Duplication Count
* Critical Issues Count
7. At end of report, output a concise Next Actions block:
- If CRITICAL issues exist: Recommend resolving before `/implement`.
- If only LOW/MEDIUM: User may proceed, but provide improvement suggestions.
- Provide explicit command suggestions: e.g., "Run /specify with refinement", "Run /plan to adjust architecture", "Manually edit tasks.md to add coverage for 'performance-metrics'".
8. Ask the user: "Would you like me to suggest concrete remediation edits for the top N issues?" (Do NOT apply them automatically.)
Behavior rules:
- NEVER modify files.
- NEVER hallucinate missing sections—if absent, report them.
- KEEP findings deterministic: if rerun without changes, produce consistent IDs and counts.
- LIMIT total findings in the main table to 50; aggregate remainder in a summarized overflow note.
- If zero issues found, emit a success report with coverage statistics and proceed recommendation.
Context: $ARGUMENTS

View File

@@ -0,0 +1,158 @@
---
description: Identify underspecified areas in the current feature spec by asking up to 5 highly targeted clarification questions and encoding answers back into the spec.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
Goal: Detect and reduce ambiguity or missing decision points in the active feature specification and record the clarifications directly in the spec file.
Note: This clarification workflow is expected to run (and be completed) BEFORE invoking `/plan`. If the user explicitly states they are skipping clarification (e.g., exploratory spike), you may proceed, but must warn that downstream rework risk increases.
Execution steps:
1. Run `.specify/scripts/bash/check-prerequisites.sh --json --paths-only` from repo root **once** (combined `--json --paths-only` mode / `-Json -PathsOnly`). Parse minimal JSON payload fields:
- `FEATURE_DIR`
- `FEATURE_SPEC`
- (Optionally capture `IMPL_PLAN`, `TASKS` for future chained flows.)
- If JSON parsing fails, abort and instruct user to re-run `/specify` or verify feature branch environment.
2. Load the current spec file. Perform a structured ambiguity & coverage scan using this taxonomy. For each category, mark status: Clear / Partial / Missing. Produce an internal coverage map used for prioritization (do not output raw map unless no questions will be asked).
Functional Scope & Behavior:
- Core user goals & success criteria
- Explicit out-of-scope declarations
- User roles / personas differentiation
Domain & Data Model:
- Entities, attributes, relationships
- Identity & uniqueness rules
- Lifecycle/state transitions
- Data volume / scale assumptions
Interaction & UX Flow:
- Critical user journeys / sequences
- Error/empty/loading states
- Accessibility or localization notes
Non-Functional Quality Attributes:
- Performance (latency, throughput targets)
- Scalability (horizontal/vertical, limits)
- Reliability & availability (uptime, recovery expectations)
- Observability (logging, metrics, tracing signals)
- Security & privacy (authN/Z, data protection, threat assumptions)
- Compliance / regulatory constraints (if any)
Integration & External Dependencies:
- External services/APIs and failure modes
- Data import/export formats
- Protocol/versioning assumptions
Edge Cases & Failure Handling:
- Negative scenarios
- Rate limiting / throttling
- Conflict resolution (e.g., concurrent edits)
Constraints & Tradeoffs:
- Technical constraints (language, storage, hosting)
- Explicit tradeoffs or rejected alternatives
Terminology & Consistency:
- Canonical glossary terms
- Avoided synonyms / deprecated terms
Completion Signals:
- Acceptance criteria testability
- Measurable Definition of Done style indicators
Misc / Placeholders:
- TODO markers / unresolved decisions
- Ambiguous adjectives ("robust", "intuitive") lacking quantification
For each category with Partial or Missing status, add a candidate question opportunity unless:
- Clarification would not materially change implementation or validation strategy
- Information is better deferred to planning phase (note internally)
3. Generate (internally) a prioritized queue of candidate clarification questions (maximum 5). Do NOT output them all at once. Apply these constraints:
- Maximum of 5 total questions across the whole session.
- Each question must be answerable with EITHER:
* A short multiplechoice selection (25 distinct, mutually exclusive options), OR
* A one-word / shortphrase answer (explicitly constrain: "Answer in <=5 words").
- Only include questions whose answers materially impact architecture, data modeling, task decomposition, test design, UX behavior, operational readiness, or compliance validation.
- Ensure category coverage balance: attempt to cover the highest impact unresolved categories first; avoid asking two low-impact questions when a single high-impact area (e.g., security posture) is unresolved.
- Exclude questions already answered, trivial stylistic preferences, or plan-level execution details (unless blocking correctness).
- Favor clarifications that reduce downstream rework risk or prevent misaligned acceptance tests.
- If more than 5 categories remain unresolved, select the top 5 by (Impact * Uncertainty) heuristic.
4. Sequential questioning loop (interactive):
- Present EXACTLY ONE question at a time.
- For multiplechoice questions render options as a Markdown table:
| Option | Description |
|--------|-------------|
| A | <Option A description> |
| B | <Option B description> |
| C | <Option C description> | (add D/E as needed up to 5)
| Short | Provide a different short answer (<=5 words) | (Include only if free-form alternative is appropriate)
- For shortanswer style (no meaningful discrete options), output a single line after the question: `Format: Short answer (<=5 words)`.
- After the user answers:
* Validate the answer maps to one option or fits the <=5 word constraint.
* If ambiguous, ask for a quick disambiguation (count still belongs to same question; do not advance).
* Once satisfactory, record it in working memory (do not yet write to disk) and move to the next queued question.
- Stop asking further questions when:
* All critical ambiguities resolved early (remaining queued items become unnecessary), OR
* User signals completion ("done", "good", "no more"), OR
* You reach 5 asked questions.
- Never reveal future queued questions in advance.
- If no valid questions exist at start, immediately report no critical ambiguities.
5. Integration after EACH accepted answer (incremental update approach):
- Maintain in-memory representation of the spec (loaded once at start) plus the raw file contents.
- For the first integrated answer in this session:
* Ensure a `## Clarifications` section exists (create it just after the highest-level contextual/overview section per the spec template if missing).
* Under it, create (if not present) a `### Session YYYY-MM-DD` subheading for today.
- Append a bullet line immediately after acceptance: `- Q: <question> → A: <final answer>`.
- Then immediately apply the clarification to the most appropriate section(s):
* Functional ambiguity → Update or add a bullet in Functional Requirements.
* User interaction / actor distinction → Update User Stories or Actors subsection (if present) with clarified role, constraint, or scenario.
* Data shape / entities → Update Data Model (add fields, types, relationships) preserving ordering; note added constraints succinctly.
* Non-functional constraint → Add/modify measurable criteria in Non-Functional / Quality Attributes section (convert vague adjective to metric or explicit target).
* Edge case / negative flow → Add a new bullet under Edge Cases / Error Handling (or create such subsection if template provides placeholder for it).
* Terminology conflict → Normalize term across spec; retain original only if necessary by adding `(formerly referred to as "X")` once.
- If the clarification invalidates an earlier ambiguous statement, replace that statement instead of duplicating; leave no obsolete contradictory text.
- Save the spec file AFTER each integration to minimize risk of context loss (atomic overwrite).
- Preserve formatting: do not reorder unrelated sections; keep heading hierarchy intact.
- Keep each inserted clarification minimal and testable (avoid narrative drift).
6. Validation (performed after EACH write plus final pass):
- Clarifications session contains exactly one bullet per accepted answer (no duplicates).
- Total asked (accepted) questions ≤ 5.
- Updated sections contain no lingering vague placeholders the new answer was meant to resolve.
- No contradictory earlier statement remains (scan for now-invalid alternative choices removed).
- Markdown structure valid; only allowed new headings: `## Clarifications`, `### Session YYYY-MM-DD`.
- Terminology consistency: same canonical term used across all updated sections.
7. Write the updated spec back to `FEATURE_SPEC`.
8. Report completion (after questioning loop ends or early termination):
- Number of questions asked & answered.
- Path to updated spec.
- Sections touched (list names).
- Coverage summary table listing each taxonomy category with Status: Resolved (was Partial/Missing and addressed), Deferred (exceeds question quota or better suited for planning), Clear (already sufficient), Outstanding (still Partial/Missing but low impact).
- If any Outstanding or Deferred remain, recommend whether to proceed to `/plan` or run `/clarify` again later post-plan.
- Suggested next command.
Behavior rules:
- If no meaningful ambiguities found (or all potential questions would be low-impact), respond: "No critical ambiguities detected worth formal clarification." and suggest proceeding.
- If spec file missing, instruct user to run `/specify` first (do not create a new spec here).
- Never exceed 5 total asked questions (clarification retries for a single question do not count as new questions).
- Avoid speculative tech stack questions unless the absence blocks functional clarity.
- Respect user early termination signals ("stop", "done", "proceed").
- If no questions asked due to full coverage, output a compact coverage summary (all categories Clear) then suggest advancing.
- If quota reached with unresolved high-impact categories remaining, explicitly flag them under Deferred with rationale.
Context for prioritization: $ARGUMENTS

View File

@@ -0,0 +1,73 @@
---
description: Create or update the project constitution from interactive or provided principle inputs, ensuring all dependent templates stay in sync.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
You are updating the project constitution at `.specify/memory/constitution.md`. This file is a TEMPLATE containing placeholder tokens in square brackets (e.g. `[PROJECT_NAME]`, `[PRINCIPLE_1_NAME]`). Your job is to (a) collect/derive concrete values, (b) fill the template precisely, and (c) propagate any amendments across dependent artifacts.
Follow this execution flow:
1. Load the existing constitution template at `.specify/memory/constitution.md`.
- Identify every placeholder token of the form `[ALL_CAPS_IDENTIFIER]`.
**IMPORTANT**: The user might require less or more principles than the ones used in the template. If a number is specified, respect that - follow the general template. You will update the doc accordingly.
2. Collect/derive values for placeholders:
- If user input (conversation) supplies a value, use it.
- Otherwise infer from existing repo context (README, docs, prior constitution versions if embedded).
- For governance dates: `RATIFICATION_DATE` is the original adoption date (if unknown ask or mark TODO), `LAST_AMENDED_DATE` is today if changes are made, otherwise keep previous.
- `CONSTITUTION_VERSION` must increment according to semantic versioning rules:
* MAJOR: Backward incompatible governance/principle removals or redefinitions.
* MINOR: New principle/section added or materially expanded guidance.
* PATCH: Clarifications, wording, typo fixes, non-semantic refinements.
- If version bump type ambiguous, propose reasoning before finalizing.
3. Draft the updated constitution content:
- Replace every placeholder with concrete text (no bracketed tokens left except intentionally retained template slots that the project has chosen not to define yet—explicitly justify any left).
- Preserve heading hierarchy and comments can be removed once replaced unless they still add clarifying guidance.
- Ensure each Principle section: succinct name line, paragraph (or bullet list) capturing nonnegotiable rules, explicit rationale if not obvious.
- Ensure Governance section lists amendment procedure, versioning policy, and compliance review expectations.
4. Consistency propagation checklist (convert prior checklist into active validations):
- Read `.specify/templates/plan-template.md` and ensure any "Constitution Check" or rules align with updated principles.
- Read `.specify/templates/spec-template.md` for scope/requirements alignment—update if constitution adds/removes mandatory sections or constraints.
- Read `.specify/templates/tasks-template.md` and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline).
- Read each command file in `.specify/templates/commands/*.md` (including this one) to verify no outdated references (agent-specific names like CLAUDE only) remain when generic guidance is required.
- Read any runtime guidance docs (e.g., `README.md`, `docs/quickstart.md`, or agent-specific guidance files if present). Update references to principles changed.
5. Produce a Sync Impact Report (prepend as an HTML comment at top of the constitution file after update):
- Version change: old → new
- List of modified principles (old title → new title if renamed)
- Added sections
- Removed sections
- Templates requiring updates (✅ updated / ⚠ pending) with file paths
- Follow-up TODOs if any placeholders intentionally deferred.
6. Validation before final output:
- No remaining unexplained bracket tokens.
- Version line matches report.
- Dates ISO format YYYY-MM-DD.
- Principles are declarative, testable, and free of vague language ("should" → replace with MUST/SHOULD rationale where appropriate).
7. Write the completed constitution back to `.specify/memory/constitution.md` (overwrite).
8. Output a final summary to the user with:
- New version and bump rationale.
- Any files flagged for manual follow-up.
- Suggested commit message (e.g., `docs: amend constitution to vX.Y.Z (principle additions + governance update)`).
Formatting & Style Requirements:
- Use Markdown headings exactly as in the template (do not demote/promote levels).
- Wrap long rationale lines to keep readability (<100 chars ideally) but do not hard enforce with awkward breaks.
- Keep a single blank line between sections.
- Avoid trailing whitespace.
If the user supplies partial updates (e.g., only one principle revision), still perform validation and version decision steps.
If critical info missing (e.g., ratification date truly unknown), insert `TODO(<FIELD_NAME>): explanation` and include in the Sync Impact Report under deferred items.
Do not create a new template; always operate on the existing `.specify/memory/constitution.md` file.

View File

@@ -0,0 +1,56 @@
---
description: Execute the implementation plan by processing and executing all tasks defined in tasks.md
---
The user input can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
1. Run `.specify/scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks` from repo root and parse FEATURE_DIR and AVAILABLE_DOCS list. All paths must be absolute.
2. Load and analyze the implementation context:
- **REQUIRED**: Read tasks.md for the complete task list and execution plan
- **REQUIRED**: Read plan.md for tech stack, architecture, and file structure
- **IF EXISTS**: Read data-model.md for entities and relationships
- **IF EXISTS**: Read contracts/ for API specifications and test requirements
- **IF EXISTS**: Read research.md for technical decisions and constraints
- **IF EXISTS**: Read quickstart.md for integration scenarios
3. Parse tasks.md structure and extract:
- **Task phases**: Setup, Tests, Core, Integration, Polish
- **Task dependencies**: Sequential vs parallel execution rules
- **Task details**: ID, description, file paths, parallel markers [P]
- **Execution flow**: Order and dependency requirements
4. Execute implementation following the task plan:
- **Phase-by-phase execution**: Complete each phase before moving to the next
- **Respect dependencies**: Run sequential tasks in order, parallel tasks [P] can run together
- **Follow TDD approach**: Execute test tasks before their corresponding implementation tasks
- **File-based coordination**: Tasks affecting the same files must run sequentially
- **Validation checkpoints**: Verify each phase completion before proceeding
5. Implementation execution rules:
- **Setup first**: Initialize project structure, dependencies, configuration
- **Tests before code**: If you need to write tests for contracts, entities, and integration scenarios
- **Core development**: Implement models, services, CLI commands, endpoints
- **Integration work**: Database connections, middleware, logging, external services
- **Polish and validation**: Unit tests, performance optimization, documentation
6. Progress tracking and error handling:
- Report progress after each completed task
- Halt execution if any non-parallel task fails
- For parallel tasks [P], continue with successful tasks, report failed ones
- Provide clear error messages with context for debugging
- Suggest next steps if implementation cannot proceed
- **IMPORTANT** For completed tasks, make sure to mark the task off as [X] in the tasks file.
7. Completion validation:
- Verify all required tasks are completed
- Check that implemented features match the original specification
- Validate that tests pass and coverage meets requirements
- Confirm the implementation follows the technical plan
- Report final status with summary of completed work
Note: This command assumes a complete task breakdown exists in tasks.md. If tasks are incomplete or missing, suggest running `/tasks` first to regenerate the task list.

View File

@@ -0,0 +1,43 @@
---
description: Execute the implementation planning workflow using the plan template to generate design artifacts.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
Given the implementation details provided as an argument, do this:
1. Run `.specify/scripts/bash/setup-plan.sh --json` from the repo root and parse JSON for FEATURE_SPEC, IMPL_PLAN, SPECS_DIR, BRANCH. All future file paths must be absolute.
- BEFORE proceeding, inspect FEATURE_SPEC for a `## Clarifications` section with at least one `Session` subheading. If missing or clearly ambiguous areas remain (vague adjectives, unresolved critical choices), PAUSE and instruct the user to run `/clarify` first to reduce rework. Only continue if: (a) Clarifications exist OR (b) an explicit user override is provided (e.g., "proceed without clarification"). Do not attempt to fabricate clarifications yourself.
2. Read and analyze the feature specification to understand:
- The feature requirements and user stories
- Functional and non-functional requirements
- Success criteria and acceptance criteria
- Any technical constraints or dependencies mentioned
3. Read the constitution at `.specify/memory/constitution.md` to understand constitutional requirements.
4. Execute the implementation plan template:
- Load `.specify/templates/plan-template.md` (already copied to IMPL_PLAN path)
- Set Input path to FEATURE_SPEC
- Run the Execution Flow (main) function steps 1-9
- The template is self-contained and executable
- Follow error handling and gate checks as specified
- Let the template guide artifact generation in $SPECS_DIR:
* Phase 0 generates research.md
* Phase 1 generates data-model.md, contracts/, quickstart.md
* Phase 2 generates tasks.md
- Incorporate user-provided details from arguments into Technical Context: $ARGUMENTS
- Update Progress Tracking as you complete each phase
5. Verify execution completed:
- Check Progress Tracking shows all phases complete
- Ensure all required artifacts were generated
- Confirm no ERROR states in execution
6. Report results with branch name, file paths, and generated artifacts.
Use absolute paths with the repository root for all file operations to avoid path issues.

View File

@@ -0,0 +1,21 @@
---
description: Create or update the feature specification from a natural language feature description.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
The text the user typed after `/specify` in the triggering message **is** the feature description. Assume you always have it available in this conversation even if `$ARGUMENTS` appears literally below. Do not ask the user to repeat it unless they provided an empty command.
Given that feature description, do this:
1. Run the script `.specify/scripts/bash/create-new-feature.sh --json "$ARGUMENTS"` from repo root and parse its JSON output for BRANCH_NAME and SPEC_FILE. All file paths must be absolute.
**IMPORTANT** You must only ever run this script once. The JSON is provided in the terminal as output - always refer to it to get the actual content you're looking for.
2. Load `.specify/templates/spec-template.md` to understand required sections.
3. Write the specification to SPEC_FILE using the template structure, replacing placeholders with concrete details derived from the feature description (arguments) while preserving section order and headings.
4. Report completion with branch name, spec file path, and readiness for the next phase.
Note: The script creates and checks out the new branch and initializes the spec file before writing.

View File

@@ -0,0 +1,62 @@
---
description: Generate an actionable, dependency-ordered tasks.md for the feature based on available design artifacts.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
1. Run `.specify/scripts/bash/check-prerequisites.sh --json` from repo root and parse FEATURE_DIR and AVAILABLE_DOCS list. All paths must be absolute.
2. Load and analyze available design documents:
- Always read plan.md for tech stack and libraries
- IF EXISTS: Read data-model.md for entities
- IF EXISTS: Read contracts/ for API endpoints
- IF EXISTS: Read research.md for technical decisions
- IF EXISTS: Read quickstart.md for test scenarios
Note: Not all projects have all documents. For example:
- CLI tools might not have contracts/
- Simple libraries might not need data-model.md
- Generate tasks based on what's available
3. Generate tasks following the template:
- Use `.specify/templates/tasks-template.md` as the base
- Replace example tasks with actual tasks based on:
* **Setup tasks**: Project init, dependencies, linting
* **Test tasks [P]**: One per contract, one per integration scenario
* **Core tasks**: One per entity, service, CLI command, endpoint
* **Integration tasks**: DB connections, middleware, logging
* **Polish tasks [P]**: Unit tests, performance, docs
4. Task generation rules:
- Each contract file → contract test task marked [P]
- Each entity in data-model → model creation task marked [P]
- Each endpoint → implementation task (not parallel if shared files)
- Each user story → integration test marked [P]
- Different files = can be parallel [P]
- Same file = sequential (no [P])
5. Order tasks by dependencies:
- Setup before everything
- Tests before implementation (TDD)
- Models before services
- Services before endpoints
- Core before integration
- Everything before polish
6. Include parallel execution examples:
- Group [P] tasks that can run together
- Show actual Task agent commands
7. Create FEATURE_DIR/tasks.md with:
- Correct feature name from implementation plan
- Numbered tasks (T001, T002, etc.)
- Clear file paths for each task
- Dependency notes
- Parallel execution guidance
Context for task generation: $ARGUMENTS
The tasks.md should be immediately executable - each task must be specific enough that an LLM can complete it without additional context.

View File

@@ -0,0 +1,101 @@
---
description: Perform a non-destructive cross-artifact consistency and quality analysis across spec.md, plan.md, and tasks.md after task generation.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
Goal: Identify inconsistencies, duplications, ambiguities, and underspecified items across the three core artifacts (`spec.md`, `plan.md`, `tasks.md`) before implementation. This command MUST run only after `/tasks` has successfully produced a complete `tasks.md`.
STRICTLY READ-ONLY: Do **not** modify any files. Output a structured analysis report. Offer an optional remediation plan (user must explicitly approve before any follow-up editing commands would be invoked manually).
Constitution Authority: The project constitution (`.specify/memory/constitution.md`) is **non-negotiable** within this analysis scope. Constitution conflicts are automatically CRITICAL and require adjustment of the spec, plan, or tasks—not dilution, reinterpretation, or silent ignoring of the principle. If a principle itself needs to change, that must occur in a separate, explicit constitution update outside `/analyze`.
Execution steps:
1. Run `.specify/scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks` once from repo root and parse JSON for FEATURE_DIR and AVAILABLE_DOCS. Derive absolute paths:
- SPEC = FEATURE_DIR/spec.md
- PLAN = FEATURE_DIR/plan.md
- TASKS = FEATURE_DIR/tasks.md
Abort with an error message if any required file is missing (instruct the user to run missing prerequisite command).
2. Load artifacts:
- Parse spec.md sections: Overview/Context, Functional Requirements, Non-Functional Requirements, User Stories, Edge Cases (if present).
- Parse plan.md: Architecture/stack choices, Data Model references, Phases, Technical constraints.
- Parse tasks.md: Task IDs, descriptions, phase grouping, parallel markers [P], referenced file paths.
- Load constitution `.specify/memory/constitution.md` for principle validation.
3. Build internal semantic models:
- Requirements inventory: Each functional + non-functional requirement with a stable key (derive slug based on imperative phrase; e.g., "User can upload file" -> `user-can-upload-file`).
- User story/action inventory.
- Task coverage mapping: Map each task to one or more requirements or stories (inference by keyword / explicit reference patterns like IDs or key phrases).
- Constitution rule set: Extract principle names and any MUST/SHOULD normative statements.
4. Detection passes:
A. Duplication detection:
- Identify near-duplicate requirements. Mark lower-quality phrasing for consolidation.
B. Ambiguity detection:
- Flag vague adjectives (fast, scalable, secure, intuitive, robust) lacking measurable criteria.
- Flag unresolved placeholders (TODO, TKTK, ???, <placeholder>, etc.).
C. Underspecification:
- Requirements with verbs but missing object or measurable outcome.
- User stories missing acceptance criteria alignment.
- Tasks referencing files or components not defined in spec/plan.
D. Constitution alignment:
- Any requirement or plan element conflicting with a MUST principle.
- Missing mandated sections or quality gates from constitution.
E. Coverage gaps:
- Requirements with zero associated tasks.
- Tasks with no mapped requirement/story.
- Non-functional requirements not reflected in tasks (e.g., performance, security).
F. Inconsistency:
- Terminology drift (same concept named differently across files).
- Data entities referenced in plan but absent in spec (or vice versa).
- Task ordering contradictions (e.g., integration tasks before foundational setup tasks without dependency note).
- Conflicting requirements (e.g., one requires to use Next.js while other says to use Vue as the framework).
5. Severity assignment heuristic:
- CRITICAL: Violates constitution MUST, missing core spec artifact, or requirement with zero coverage that blocks baseline functionality.
- HIGH: Duplicate or conflicting requirement, ambiguous security/performance attribute, untestable acceptance criterion.
- MEDIUM: Terminology drift, missing non-functional task coverage, underspecified edge case.
- LOW: Style/wording improvements, minor redundancy not affecting execution order.
6. Produce a Markdown report (no file writes) with sections:
### Specification Analysis Report
| ID | Category | Severity | Location(s) | Summary | Recommendation |
|----|----------|----------|-------------|---------|----------------|
| A1 | Duplication | HIGH | spec.md:L120-134 | Two similar requirements ... | Merge phrasing; keep clearer version |
(Add one row per finding; generate stable IDs prefixed by category initial.)
Additional subsections:
- Coverage Summary Table:
| Requirement Key | Has Task? | Task IDs | Notes |
- Constitution Alignment Issues (if any)
- Unmapped Tasks (if any)
- Metrics:
* Total Requirements
* Total Tasks
* Coverage % (requirements with >=1 task)
* Ambiguity Count
* Duplication Count
* Critical Issues Count
7. At end of report, output a concise Next Actions block:
- If CRITICAL issues exist: Recommend resolving before `/implement`.
- If only LOW/MEDIUM: User may proceed, but provide improvement suggestions.
- Provide explicit command suggestions: e.g., "Run /specify with refinement", "Run /plan to adjust architecture", "Manually edit tasks.md to add coverage for 'performance-metrics'".
8. Ask the user: "Would you like me to suggest concrete remediation edits for the top N issues?" (Do NOT apply them automatically.)
Behavior rules:
- NEVER modify files.
- NEVER hallucinate missing sections—if absent, report them.
- KEEP findings deterministic: if rerun without changes, produce consistent IDs and counts.
- LIMIT total findings in the main table to 50; aggregate remainder in a summarized overflow note.
- If zero issues found, emit a success report with coverage statistics and proceed recommendation.
Context: $ARGUMENTS

View File

@@ -0,0 +1,158 @@
---
description: Identify underspecified areas in the current feature spec by asking up to 5 highly targeted clarification questions and encoding answers back into the spec.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
Goal: Detect and reduce ambiguity or missing decision points in the active feature specification and record the clarifications directly in the spec file.
Note: This clarification workflow is expected to run (and be completed) BEFORE invoking `/plan`. If the user explicitly states they are skipping clarification (e.g., exploratory spike), you may proceed, but must warn that downstream rework risk increases.
Execution steps:
1. Run `.specify/scripts/bash/check-prerequisites.sh --json --paths-only` from repo root **once** (combined `--json --paths-only` mode / `-Json -PathsOnly`). Parse minimal JSON payload fields:
- `FEATURE_DIR`
- `FEATURE_SPEC`
- (Optionally capture `IMPL_PLAN`, `TASKS` for future chained flows.)
- If JSON parsing fails, abort and instruct user to re-run `/specify` or verify feature branch environment.
2. Load the current spec file. Perform a structured ambiguity & coverage scan using this taxonomy. For each category, mark status: Clear / Partial / Missing. Produce an internal coverage map used for prioritization (do not output raw map unless no questions will be asked).
Functional Scope & Behavior:
- Core user goals & success criteria
- Explicit out-of-scope declarations
- User roles / personas differentiation
Domain & Data Model:
- Entities, attributes, relationships
- Identity & uniqueness rules
- Lifecycle/state transitions
- Data volume / scale assumptions
Interaction & UX Flow:
- Critical user journeys / sequences
- Error/empty/loading states
- Accessibility or localization notes
Non-Functional Quality Attributes:
- Performance (latency, throughput targets)
- Scalability (horizontal/vertical, limits)
- Reliability & availability (uptime, recovery expectations)
- Observability (logging, metrics, tracing signals)
- Security & privacy (authN/Z, data protection, threat assumptions)
- Compliance / regulatory constraints (if any)
Integration & External Dependencies:
- External services/APIs and failure modes
- Data import/export formats
- Protocol/versioning assumptions
Edge Cases & Failure Handling:
- Negative scenarios
- Rate limiting / throttling
- Conflict resolution (e.g., concurrent edits)
Constraints & Tradeoffs:
- Technical constraints (language, storage, hosting)
- Explicit tradeoffs or rejected alternatives
Terminology & Consistency:
- Canonical glossary terms
- Avoided synonyms / deprecated terms
Completion Signals:
- Acceptance criteria testability
- Measurable Definition of Done style indicators
Misc / Placeholders:
- TODO markers / unresolved decisions
- Ambiguous adjectives ("robust", "intuitive") lacking quantification
For each category with Partial or Missing status, add a candidate question opportunity unless:
- Clarification would not materially change implementation or validation strategy
- Information is better deferred to planning phase (note internally)
3. Generate (internally) a prioritized queue of candidate clarification questions (maximum 5). Do NOT output them all at once. Apply these constraints:
- Maximum of 5 total questions across the whole session.
- Each question must be answerable with EITHER:
* A short multiplechoice selection (25 distinct, mutually exclusive options), OR
* A one-word / shortphrase answer (explicitly constrain: "Answer in <=5 words").
- Only include questions whose answers materially impact architecture, data modeling, task decomposition, test design, UX behavior, operational readiness, or compliance validation.
- Ensure category coverage balance: attempt to cover the highest impact unresolved categories first; avoid asking two low-impact questions when a single high-impact area (e.g., security posture) is unresolved.
- Exclude questions already answered, trivial stylistic preferences, or plan-level execution details (unless blocking correctness).
- Favor clarifications that reduce downstream rework risk or prevent misaligned acceptance tests.
- If more than 5 categories remain unresolved, select the top 5 by (Impact * Uncertainty) heuristic.
4. Sequential questioning loop (interactive):
- Present EXACTLY ONE question at a time.
- For multiplechoice questions render options as a Markdown table:
| Option | Description |
|--------|-------------|
| A | <Option A description> |
| B | <Option B description> |
| C | <Option C description> | (add D/E as needed up to 5)
| Short | Provide a different short answer (<=5 words) | (Include only if free-form alternative is appropriate)
- For shortanswer style (no meaningful discrete options), output a single line after the question: `Format: Short answer (<=5 words)`.
- After the user answers:
* Validate the answer maps to one option or fits the <=5 word constraint.
* If ambiguous, ask for a quick disambiguation (count still belongs to same question; do not advance).
* Once satisfactory, record it in working memory (do not yet write to disk) and move to the next queued question.
- Stop asking further questions when:
* All critical ambiguities resolved early (remaining queued items become unnecessary), OR
* User signals completion ("done", "good", "no more"), OR
* You reach 5 asked questions.
- Never reveal future queued questions in advance.
- If no valid questions exist at start, immediately report no critical ambiguities.
5. Integration after EACH accepted answer (incremental update approach):
- Maintain in-memory representation of the spec (loaded once at start) plus the raw file contents.
- For the first integrated answer in this session:
* Ensure a `## Clarifications` section exists (create it just after the highest-level contextual/overview section per the spec template if missing).
* Under it, create (if not present) a `### Session YYYY-MM-DD` subheading for today.
- Append a bullet line immediately after acceptance: `- Q: <question> → A: <final answer>`.
- Then immediately apply the clarification to the most appropriate section(s):
* Functional ambiguity → Update or add a bullet in Functional Requirements.
* User interaction / actor distinction → Update User Stories or Actors subsection (if present) with clarified role, constraint, or scenario.
* Data shape / entities → Update Data Model (add fields, types, relationships) preserving ordering; note added constraints succinctly.
* Non-functional constraint → Add/modify measurable criteria in Non-Functional / Quality Attributes section (convert vague adjective to metric or explicit target).
* Edge case / negative flow → Add a new bullet under Edge Cases / Error Handling (or create such subsection if template provides placeholder for it).
* Terminology conflict → Normalize term across spec; retain original only if necessary by adding `(formerly referred to as "X")` once.
- If the clarification invalidates an earlier ambiguous statement, replace that statement instead of duplicating; leave no obsolete contradictory text.
- Save the spec file AFTER each integration to minimize risk of context loss (atomic overwrite).
- Preserve formatting: do not reorder unrelated sections; keep heading hierarchy intact.
- Keep each inserted clarification minimal and testable (avoid narrative drift).
6. Validation (performed after EACH write plus final pass):
- Clarifications session contains exactly one bullet per accepted answer (no duplicates).
- Total asked (accepted) questions ≤ 5.
- Updated sections contain no lingering vague placeholders the new answer was meant to resolve.
- No contradictory earlier statement remains (scan for now-invalid alternative choices removed).
- Markdown structure valid; only allowed new headings: `## Clarifications`, `### Session YYYY-MM-DD`.
- Terminology consistency: same canonical term used across all updated sections.
7. Write the updated spec back to `FEATURE_SPEC`.
8. Report completion (after questioning loop ends or early termination):
- Number of questions asked & answered.
- Path to updated spec.
- Sections touched (list names).
- Coverage summary table listing each taxonomy category with Status: Resolved (was Partial/Missing and addressed), Deferred (exceeds question quota or better suited for planning), Clear (already sufficient), Outstanding (still Partial/Missing but low impact).
- If any Outstanding or Deferred remain, recommend whether to proceed to `/plan` or run `/clarify` again later post-plan.
- Suggested next command.
Behavior rules:
- If no meaningful ambiguities found (or all potential questions would be low-impact), respond: "No critical ambiguities detected worth formal clarification." and suggest proceeding.
- If spec file missing, instruct user to run `/specify` first (do not create a new spec here).
- Never exceed 5 total asked questions (clarification retries for a single question do not count as new questions).
- Avoid speculative tech stack questions unless the absence blocks functional clarity.
- Respect user early termination signals ("stop", "done", "proceed").
- If no questions asked due to full coverage, output a compact coverage summary (all categories Clear) then suggest advancing.
- If quota reached with unresolved high-impact categories remaining, explicitly flag them under Deferred with rationale.
Context for prioritization: $ARGUMENTS

View File

@@ -0,0 +1,73 @@
---
description: Create or update the project constitution from interactive or provided principle inputs, ensuring all dependent templates stay in sync.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
You are updating the project constitution at `.specify/memory/constitution.md`. This file is a TEMPLATE containing placeholder tokens in square brackets (e.g. `[PROJECT_NAME]`, `[PRINCIPLE_1_NAME]`). Your job is to (a) collect/derive concrete values, (b) fill the template precisely, and (c) propagate any amendments across dependent artifacts.
Follow this execution flow:
1. Load the existing constitution template at `.specify/memory/constitution.md`.
- Identify every placeholder token of the form `[ALL_CAPS_IDENTIFIER]`.
**IMPORTANT**: The user might require less or more principles than the ones used in the template. If a number is specified, respect that - follow the general template. You will update the doc accordingly.
2. Collect/derive values for placeholders:
- If user input (conversation) supplies a value, use it.
- Otherwise infer from existing repo context (README, docs, prior constitution versions if embedded).
- For governance dates: `RATIFICATION_DATE` is the original adoption date (if unknown ask or mark TODO), `LAST_AMENDED_DATE` is today if changes are made, otherwise keep previous.
- `CONSTITUTION_VERSION` must increment according to semantic versioning rules:
* MAJOR: Backward incompatible governance/principle removals or redefinitions.
* MINOR: New principle/section added or materially expanded guidance.
* PATCH: Clarifications, wording, typo fixes, non-semantic refinements.
- If version bump type ambiguous, propose reasoning before finalizing.
3. Draft the updated constitution content:
- Replace every placeholder with concrete text (no bracketed tokens left except intentionally retained template slots that the project has chosen not to define yet—explicitly justify any left).
- Preserve heading hierarchy and comments can be removed once replaced unless they still add clarifying guidance.
- Ensure each Principle section: succinct name line, paragraph (or bullet list) capturing nonnegotiable rules, explicit rationale if not obvious.
- Ensure Governance section lists amendment procedure, versioning policy, and compliance review expectations.
4. Consistency propagation checklist (convert prior checklist into active validations):
- Read `.specify/templates/plan-template.md` and ensure any "Constitution Check" or rules align with updated principles.
- Read `.specify/templates/spec-template.md` for scope/requirements alignment—update if constitution adds/removes mandatory sections or constraints.
- Read `.specify/templates/tasks-template.md` and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline).
- Read each command file in `.specify/templates/commands/*.md` (including this one) to verify no outdated references (agent-specific names like CLAUDE only) remain when generic guidance is required.
- Read any runtime guidance docs (e.g., `README.md`, `docs/quickstart.md`, or agent-specific guidance files if present). Update references to principles changed.
5. Produce a Sync Impact Report (prepend as an HTML comment at top of the constitution file after update):
- Version change: old → new
- List of modified principles (old title → new title if renamed)
- Added sections
- Removed sections
- Templates requiring updates (✅ updated / ⚠ pending) with file paths
- Follow-up TODOs if any placeholders intentionally deferred.
6. Validation before final output:
- No remaining unexplained bracket tokens.
- Version line matches report.
- Dates ISO format YYYY-MM-DD.
- Principles are declarative, testable, and free of vague language ("should" → replace with MUST/SHOULD rationale where appropriate).
7. Write the completed constitution back to `.specify/memory/constitution.md` (overwrite).
8. Output a final summary to the user with:
- New version and bump rationale.
- Any files flagged for manual follow-up.
- Suggested commit message (e.g., `docs: amend constitution to vX.Y.Z (principle additions + governance update)`).
Formatting & Style Requirements:
- Use Markdown headings exactly as in the template (do not demote/promote levels).
- Wrap long rationale lines to keep readability (<100 chars ideally) but do not hard enforce with awkward breaks.
- Keep a single blank line between sections.
- Avoid trailing whitespace.
If the user supplies partial updates (e.g., only one principle revision), still perform validation and version decision steps.
If critical info missing (e.g., ratification date truly unknown), insert `TODO(<FIELD_NAME>): explanation` and include in the Sync Impact Report under deferred items.
Do not create a new template; always operate on the existing `.specify/memory/constitution.md` file.

View File

@@ -0,0 +1,56 @@
---
description: Execute the implementation plan by processing and executing all tasks defined in tasks.md
---
The user input can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
1. Run `.specify/scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks` from repo root and parse FEATURE_DIR and AVAILABLE_DOCS list. All paths must be absolute.
2. Load and analyze the implementation context:
- **REQUIRED**: Read tasks.md for the complete task list and execution plan
- **REQUIRED**: Read plan.md for tech stack, architecture, and file structure
- **IF EXISTS**: Read data-model.md for entities and relationships
- **IF EXISTS**: Read contracts/ for API specifications and test requirements
- **IF EXISTS**: Read research.md for technical decisions and constraints
- **IF EXISTS**: Read quickstart.md for integration scenarios
3. Parse tasks.md structure and extract:
- **Task phases**: Setup, Tests, Core, Integration, Polish
- **Task dependencies**: Sequential vs parallel execution rules
- **Task details**: ID, description, file paths, parallel markers [P]
- **Execution flow**: Order and dependency requirements
4. Execute implementation following the task plan:
- **Phase-by-phase execution**: Complete each phase before moving to the next
- **Respect dependencies**: Run sequential tasks in order, parallel tasks [P] can run together
- **Follow TDD approach**: Execute test tasks before their corresponding implementation tasks
- **File-based coordination**: Tasks affecting the same files must run sequentially
- **Validation checkpoints**: Verify each phase completion before proceeding
5. Implementation execution rules:
- **Setup first**: Initialize project structure, dependencies, configuration
- **Tests before code**: If you need to write tests for contracts, entities, and integration scenarios
- **Core development**: Implement models, services, CLI commands, endpoints
- **Integration work**: Database connections, middleware, logging, external services
- **Polish and validation**: Unit tests, performance optimization, documentation
6. Progress tracking and error handling:
- Report progress after each completed task
- Halt execution if any non-parallel task fails
- For parallel tasks [P], continue with successful tasks, report failed ones
- Provide clear error messages with context for debugging
- Suggest next steps if implementation cannot proceed
- **IMPORTANT** For completed tasks, make sure to mark the task off as [X] in the tasks file.
7. Completion validation:
- Verify all required tasks are completed
- Check that implemented features match the original specification
- Validate that tests pass and coverage meets requirements
- Confirm the implementation follows the technical plan
- Report final status with summary of completed work
Note: This command assumes a complete task breakdown exists in tasks.md. If tasks are incomplete or missing, suggest running `/tasks` first to regenerate the task list.

43
.opencode/command/plan.md Normal file
View File

@@ -0,0 +1,43 @@
---
description: Execute the implementation planning workflow using the plan template to generate design artifacts.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
Given the implementation details provided as an argument, do this:
1. Run `.specify/scripts/bash/setup-plan.sh --json` from the repo root and parse JSON for FEATURE_SPEC, IMPL_PLAN, SPECS_DIR, BRANCH. All future file paths must be absolute.
- BEFORE proceeding, inspect FEATURE_SPEC for a `## Clarifications` section with at least one `Session` subheading. If missing or clearly ambiguous areas remain (vague adjectives, unresolved critical choices), PAUSE and instruct the user to run `/clarify` first to reduce rework. Only continue if: (a) Clarifications exist OR (b) an explicit user override is provided (e.g., "proceed without clarification"). Do not attempt to fabricate clarifications yourself.
2. Read and analyze the feature specification to understand:
- The feature requirements and user stories
- Functional and non-functional requirements
- Success criteria and acceptance criteria
- Any technical constraints or dependencies mentioned
3. Read the constitution at `.specify/memory/constitution.md` to understand constitutional requirements.
4. Execute the implementation plan template:
- Load `.specify/templates/plan-template.md` (already copied to IMPL_PLAN path)
- Set Input path to FEATURE_SPEC
- Run the Execution Flow (main) function steps 1-9
- The template is self-contained and executable
- Follow error handling and gate checks as specified
- Let the template guide artifact generation in $SPECS_DIR:
* Phase 0 generates research.md
* Phase 1 generates data-model.md, contracts/, quickstart.md
* Phase 2 generates tasks.md
- Incorporate user-provided details from arguments into Technical Context: $ARGUMENTS
- Update Progress Tracking as you complete each phase
5. Verify execution completed:
- Check Progress Tracking shows all phases complete
- Ensure all required artifacts were generated
- Confirm no ERROR states in execution
6. Report results with branch name, file paths, and generated artifacts.
Use absolute paths with the repository root for all file operations to avoid path issues.

View File

@@ -0,0 +1,21 @@
---
description: Create or update the feature specification from a natural language feature description.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
The text the user typed after `/specify` in the triggering message **is** the feature description. Assume you always have it available in this conversation even if `$ARGUMENTS` appears literally below. Do not ask the user to repeat it unless they provided an empty command.
Given that feature description, do this:
1. Run the script `.specify/scripts/bash/create-new-feature.sh --json "$ARGUMENTS"` from repo root and parse its JSON output for BRANCH_NAME and SPEC_FILE. All file paths must be absolute.
**IMPORTANT** You must only ever run this script once. The JSON is provided in the terminal as output - always refer to it to get the actual content you're looking for.
2. Load `.specify/templates/spec-template.md` to understand required sections.
3. Write the specification to SPEC_FILE using the template structure, replacing placeholders with concrete details derived from the feature description (arguments) while preserving section order and headings.
4. Report completion with branch name, spec file path, and readiness for the next phase.
Note: The script creates and checks out the new branch and initializes the spec file before writing.

View File

@@ -0,0 +1,62 @@
---
description: Generate an actionable, dependency-ordered tasks.md for the feature based on available design artifacts.
---
The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty).
User input:
$ARGUMENTS
1. Run `.specify/scripts/bash/check-prerequisites.sh --json` from repo root and parse FEATURE_DIR and AVAILABLE_DOCS list. All paths must be absolute.
2. Load and analyze available design documents:
- Always read plan.md for tech stack and libraries
- IF EXISTS: Read data-model.md for entities
- IF EXISTS: Read contracts/ for API endpoints
- IF EXISTS: Read research.md for technical decisions
- IF EXISTS: Read quickstart.md for test scenarios
Note: Not all projects have all documents. For example:
- CLI tools might not have contracts/
- Simple libraries might not need data-model.md
- Generate tasks based on what's available
3. Generate tasks following the template:
- Use `.specify/templates/tasks-template.md` as the base
- Replace example tasks with actual tasks based on:
* **Setup tasks**: Project init, dependencies, linting
* **Test tasks [P]**: One per contract, one per integration scenario
* **Core tasks**: One per entity, service, CLI command, endpoint
* **Integration tasks**: DB connections, middleware, logging
* **Polish tasks [P]**: Unit tests, performance, docs
4. Task generation rules:
- Each contract file → contract test task marked [P]
- Each entity in data-model → model creation task marked [P]
- Each endpoint → implementation task (not parallel if shared files)
- Each user story → integration test marked [P]
- Different files = can be parallel [P]
- Same file = sequential (no [P])
5. Order tasks by dependencies:
- Setup before everything
- Tests before implementation (TDD)
- Models before services
- Services before endpoints
- Core before integration
- Everything before polish
6. Include parallel execution examples:
- Group [P] tasks that can run together
- Show actual Task agent commands
7. Create FEATURE_DIR/tasks.md with:
- Correct feature name from implementation plan
- Numbered tasks (T001, T002, etc.)
- Clear file paths for each task
- Dependency notes
- Parallel execution guidance
Context for task generation: $ARGUMENTS
The tasks.md should be immediately executable - each task must be specific enough that an LLM can complete it without additional context.

1
.roo/mcp.json Normal file
View File

@@ -0,0 +1 @@
{"mcpServers":{}}

View File

@@ -0,0 +1,72 @@
# Spec Workflow MCP Server Configuration File
# ============================================
#
# This is an example configuration file for the Spec Workflow MCP Server.
# Copy this file to 'config.toml' in the same directory to use it.
#
# Configuration Precedence:
# 1. Command-line arguments (highest priority)
# 2. Config file settings
# 3. Built-in defaults (lowest priority)
#
# All settings are optional. Uncomment and modify as needed.
# Please note that not all MCP clients will support loading this config file due to the nature of where they are running from.
# Project directory path
# The root directory of your project where spec files are located.
# Note: You may have to use double slashes (\\) instead of single slashes (/) on Windows or for certain clients.
# Supports tilde (~) expansion for home directory.
# Default: current working directory
# projectDir = "."
# projectDir = "~/my-project"
# projectDir = "/absolute/path/to/project"
# Dashboard port
# The port number for the web dashboard.
# Must be between 1024 and 65535.
# Default: ephemeral port (automatically assigned)
# port = 3000
# Auto-start dashboard
# Automatically launch the dashboard when the MCP server starts.
# The dashboard will open in your default browser.
# Default: false
# autoStartDashboard = false
# Dashboard-only mode
# Run only the web dashboard without the MCP server.
# Useful for standalone dashboard usage.
# Default: false
# dashboardOnly = false
# Language
# Set the interface language for internationalization (i18n).
# Available languages depend on your installation.
# Common values: "en" (English), "ja" (Japanese), etc.
# Default: system language or "en"
# lang = "en"
# Example configurations:
# =====================
# Example 1: Development setup with auto-started dashboard
# ----------------------------------------------------------
# projectDir = "~/dev/my-project"
# autoStartDashboard = true
# port = 3456
# Example 2: Production MCP server without dashboard
# ---------------------------------------------------
# projectDir = "/var/projects/production"
# autoStartDashboard = false
# Example 3: Dashboard-only mode for viewing specs
# -------------------------------------------------
# projectDir = "."
# dashboardOnly = true
# port = 8080
# Example 4: Japanese language interface
# ---------------------------------------
# lang = "ja"
# autoStartDashboard = true

View File

@@ -0,0 +1,96 @@
# Design Document
## Overview
[High-level description of the feature and its place in the overall system]
## Steering Document Alignment
### Technical Standards (tech.md)
[How the design follows documented technical patterns and standards]
### Project Structure (structure.md)
[How the implementation will follow project organization conventions]
## Code Reuse Analysis
[What existing code will be leveraged, extended, or integrated with this feature]
### Existing Components to Leverage
- **[Component/Utility Name]**: [How it will be used]
- **[Service/Helper Name]**: [How it will be extended]
### Integration Points
- **[Existing System/API]**: [How the new feature will integrate]
- **[Database/Storage]**: [How data will connect to existing schemas]
## Architecture
[Describe the overall architecture and design patterns used]
### Modular Design Principles
- **Single File Responsibility**: Each file should handle one specific concern or domain
- **Component Isolation**: Create small, focused components rather than large monolithic files
- **Service Layer Separation**: Separate data access, business logic, and presentation layers
- **Utility Modularity**: Break utilities into focused, single-purpose modules
```mermaid
graph TD
A[Component A] --> B[Component B]
B --> C[Component C]
```
## Components and Interfaces
### Component 1
- **Purpose:** [What this component does]
- **Interfaces:** [Public methods/APIs]
- **Dependencies:** [What it depends on]
- **Reuses:** [Existing components/utilities it builds upon]
### Component 2
- **Purpose:** [What this component does]
- **Interfaces:** [Public methods/APIs]
- **Dependencies:** [What it depends on]
- **Reuses:** [Existing components/utilities it builds upon]
## Data Models
### Model 1
```
[Define the structure of Model1 in your language]
- id: [unique identifier type]
- name: [string/text type]
- [Additional properties as needed]
```
### Model 2
```
[Define the structure of Model2 in your language]
- id: [unique identifier type]
- [Additional properties as needed]
```
## Error Handling
### Error Scenarios
1. **Scenario 1:** [Description]
- **Handling:** [How to handle]
- **User Impact:** [What user sees]
2. **Scenario 2:** [Description]
- **Handling:** [How to handle]
- **User Impact:** [What user sees]
## Testing Strategy
### Unit Testing
- [Unit testing approach]
- [Key components to test]
### Integration Testing
- [Integration testing approach]
- [Key flows to test]
### End-to-End Testing
- [E2E testing approach]
- [User scenarios to test]

View File

@@ -0,0 +1,51 @@
# Product Overview
## Product Purpose
[Describe the core purpose of this product/project. What problem does it solve?]
## Target Users
[Who are the primary users of this product? What are their needs and pain points?]
## Key Features
[List the main features that deliver value to users]
1. **Feature 1**: [Description]
2. **Feature 2**: [Description]
3. **Feature 3**: [Description]
## Business Objectives
[What are the business goals this product aims to achieve?]
- [Objective 1]
- [Objective 2]
- [Objective 3]
## Success Metrics
[How will we measure the success of this product?]
- [Metric 1]: [Target]
- [Metric 2]: [Target]
- [Metric 3]: [Target]
## Product Principles
[Core principles that guide product decisions]
1. **[Principle 1]**: [Explanation]
2. **[Principle 2]**: [Explanation]
3. **[Principle 3]**: [Explanation]
## Monitoring & Visibility (if applicable)
[How do users track progress and monitor the system?]
- **Dashboard Type**: [e.g., Web-based, CLI, Desktop app]
- **Real-time Updates**: [e.g., WebSocket, polling, push notifications]
- **Key Metrics Displayed**: [What information is most important to surface]
- **Sharing Capabilities**: [e.g., read-only links, exports, reports]
## Future Vision
[Where do we see this product evolving in the future?]
### Potential Enhancements
- **Remote Access**: [e.g., Tunnel features for sharing dashboards with stakeholders]
- **Analytics**: [e.g., Historical trends, performance metrics]
- **Collaboration**: [e.g., Multi-user support, commenting]

View File

@@ -0,0 +1,50 @@
# Requirements Document
## Introduction
[Provide a brief overview of the feature, its purpose, and its value to users]
## Alignment with Product Vision
[Explain how this feature supports the goals outlined in product.md]
## Requirements
### Requirement 1
**User Story:** As a [role], I want [feature], so that [benefit]
#### Acceptance Criteria
1. WHEN [event] THEN [system] SHALL [response]
2. IF [precondition] THEN [system] SHALL [response]
3. WHEN [event] AND [condition] THEN [system] SHALL [response]
### Requirement 2
**User Story:** As a [role], I want [feature], so that [benefit]
#### Acceptance Criteria
1. WHEN [event] THEN [system] SHALL [response]
2. IF [precondition] THEN [system] SHALL [response]
## Non-Functional Requirements
### Code Architecture and Modularity
- **Single Responsibility Principle**: Each file should have a single, well-defined purpose
- **Modular Design**: Components, utilities, and services should be isolated and reusable
- **Dependency Management**: Minimize interdependencies between modules
- **Clear Interfaces**: Define clean contracts between components and layers
### Performance
- [Performance requirements]
### Security
- [Security requirements]
### Reliability
- [Reliability requirements]
### Usability
- [Usability requirements]

View File

@@ -0,0 +1,145 @@
# Project Structure
## Directory Organization
```
[Define your project's directory structure. Examples below - adapt to your project type]
Example for a library/package:
project-root/
├── src/ # Source code
├── tests/ # Test files
├── docs/ # Documentation
├── examples/ # Usage examples
└── [build/dist/out] # Build output
Example for an application:
project-root/
├── [src/app/lib] # Main source code
├── [assets/resources] # Static resources
├── [config/settings] # Configuration
├── [scripts/tools] # Build/utility scripts
└── [tests/spec] # Test files
Common patterns:
- Group by feature/module
- Group by layer (UI, business logic, data)
- Group by type (models, controllers, views)
- Flat structure for simple projects
```
## Naming Conventions
### Files
- **Components/Modules**: [e.g., `PascalCase`, `snake_case`, `kebab-case`]
- **Services/Handlers**: [e.g., `UserService`, `user_service`, `user-service`]
- **Utilities/Helpers**: [e.g., `dateUtils`, `date_utils`, `date-utils`]
- **Tests**: [e.g., `[filename]_test`, `[filename].test`, `[filename]Test`]
### Code
- **Classes/Types**: [e.g., `PascalCase`, `CamelCase`, `snake_case`]
- **Functions/Methods**: [e.g., `camelCase`, `snake_case`, `PascalCase`]
- **Constants**: [e.g., `UPPER_SNAKE_CASE`, `SCREAMING_CASE`, `PascalCase`]
- **Variables**: [e.g., `camelCase`, `snake_case`, `lowercase`]
## Import Patterns
### Import Order
1. External dependencies
2. Internal modules
3. Relative imports
4. Style imports
### Module/Package Organization
```
[Describe your project's import/include patterns]
Examples:
- Absolute imports from project root
- Relative imports within modules
- Package/namespace organization
- Dependency management approach
```
## Code Structure Patterns
[Define common patterns for organizing code within files. Below are examples - choose what applies to your project]
### Module/Class Organization
```
Example patterns:
1. Imports/includes/dependencies
2. Constants and configuration
3. Type/interface definitions
4. Main implementation
5. Helper/utility functions
6. Exports/public API
```
### Function/Method Organization
```
Example patterns:
- Input validation first
- Core logic in the middle
- Error handling throughout
- Clear return points
```
### File Organization Principles
```
Choose what works for your project:
- One class/module per file
- Related functionality grouped together
- Public API at the top/bottom
- Implementation details hidden
```
## Code Organization Principles
1. **Single Responsibility**: Each file should have one clear purpose
2. **Modularity**: Code should be organized into reusable modules
3. **Testability**: Structure code to be easily testable
4. **Consistency**: Follow patterns established in the codebase
## Module Boundaries
[Define how different parts of your project interact and maintain separation of concerns]
Examples of boundary patterns:
- **Core vs Plugins**: Core functionality vs extensible plugins
- **Public API vs Internal**: What's exposed vs implementation details
- **Platform-specific vs Cross-platform**: OS-specific code isolation
- **Stable vs Experimental**: Production code vs experimental features
- **Dependencies direction**: Which modules can depend on which
## Code Size Guidelines
[Define your project's guidelines for file and function sizes]
Suggested guidelines:
- **File size**: [Define maximum lines per file]
- **Function/Method size**: [Define maximum lines per function]
- **Class/Module complexity**: [Define complexity limits]
- **Nesting depth**: [Maximum nesting levels]
## Dashboard/Monitoring Structure (if applicable)
[How dashboard or monitoring components are organized]
### Example Structure:
```
src/
└── dashboard/ # Self-contained dashboard subsystem
├── server/ # Backend server components
├── client/ # Frontend assets
├── shared/ # Shared types/utilities
└── public/ # Static assets
```
### Separation of Concerns
- Dashboard isolated from core business logic
- Own CLI entry point for independent operation
- Minimal dependencies on main application
- Can be disabled without affecting core functionality
## Documentation Standards
- All public APIs must have documentation
- Complex logic should include inline comments
- README files for major modules
- Follow language-specific documentation conventions

View File

@@ -0,0 +1,139 @@
# Tasks Document
- [ ] 1. Create core interfaces in src/types/feature.ts
- File: src/types/feature.ts
- Define TypeScript interfaces for feature data structures
- Extend existing base interfaces from base.ts
- Purpose: Establish type safety for feature implementation
- _Leverage: src/types/base.ts_
- _Requirements: 1.1_
- _Prompt: Role: TypeScript Developer specializing in type systems and interfaces | Task: Create comprehensive TypeScript interfaces for the feature data structures following requirements 1.1, extending existing base interfaces from src/types/base.ts | Restrictions: Do not modify existing base interfaces, maintain backward compatibility, follow project naming conventions | Success: All interfaces compile without errors, proper inheritance from base types, full type coverage for feature requirements_
- [ ] 2. Create base model class in src/models/FeatureModel.ts
- File: src/models/FeatureModel.ts
- Implement base model extending BaseModel class
- Add validation methods using existing validation utilities
- Purpose: Provide data layer foundation for feature
- _Leverage: src/models/BaseModel.ts, src/utils/validation.ts_
- _Requirements: 2.1_
- _Prompt: Role: Backend Developer with expertise in Node.js and data modeling | Task: Create a base model class extending BaseModel and implementing validation following requirement 2.1, leveraging existing patterns from src/models/BaseModel.ts and src/utils/validation.ts | Restrictions: Must follow existing model patterns, do not bypass validation utilities, maintain consistent error handling | Success: Model extends BaseModel correctly, validation methods implemented and tested, follows project architecture patterns_
- [ ] 3. Add specific model methods to FeatureModel.ts
- File: src/models/FeatureModel.ts (continue from task 2)
- Implement create, update, delete methods
- Add relationship handling for foreign keys
- Purpose: Complete model functionality for CRUD operations
- _Leverage: src/models/BaseModel.ts_
- _Requirements: 2.2, 2.3_
- _Prompt: Role: Backend Developer with expertise in ORM and database operations | Task: Implement CRUD methods and relationship handling in FeatureModel.ts following requirements 2.2 and 2.3, extending patterns from src/models/BaseModel.ts | Restrictions: Must maintain transaction integrity, follow existing relationship patterns, do not duplicate base model functionality | Success: All CRUD operations work correctly, relationships are properly handled, database operations are atomic and efficient_
- [ ] 4. Create model unit tests in tests/models/FeatureModel.test.ts
- File: tests/models/FeatureModel.test.ts
- Write tests for model validation and CRUD methods
- Use existing test utilities and fixtures
- Purpose: Ensure model reliability and catch regressions
- _Leverage: tests/helpers/testUtils.ts, tests/fixtures/data.ts_
- _Requirements: 2.1, 2.2_
- _Prompt: Role: QA Engineer with expertise in unit testing and Jest/Mocha frameworks | Task: Create comprehensive unit tests for FeatureModel validation and CRUD methods covering requirements 2.1 and 2.2, using existing test utilities from tests/helpers/testUtils.ts and fixtures from tests/fixtures/data.ts | Restrictions: Must test both success and failure scenarios, do not test external dependencies directly, maintain test isolation | Success: All model methods are tested with good coverage, edge cases covered, tests run independently and consistently_
- [ ] 5. Create service interface in src/services/IFeatureService.ts
- File: src/services/IFeatureService.ts
- Define service contract with method signatures
- Extend base service interface patterns
- Purpose: Establish service layer contract for dependency injection
- _Leverage: src/services/IBaseService.ts_
- _Requirements: 3.1_
- _Prompt: Role: Software Architect specializing in service-oriented architecture and TypeScript interfaces | Task: Design service interface contract following requirement 3.1, extending base service patterns from src/services/IBaseService.ts for dependency injection | Restrictions: Must maintain interface segregation principle, do not expose internal implementation details, ensure contract compatibility with DI container | Success: Interface is well-defined with clear method signatures, extends base service appropriately, supports all required service operations_
- [ ] 6. Implement feature service in src/services/FeatureService.ts
- File: src/services/FeatureService.ts
- Create concrete service implementation using FeatureModel
- Add error handling with existing error utilities
- Purpose: Provide business logic layer for feature operations
- _Leverage: src/services/BaseService.ts, src/utils/errorHandler.ts, src/models/FeatureModel.ts_
- _Requirements: 3.2_
- _Prompt: Role: Backend Developer with expertise in service layer architecture and business logic | Task: Implement concrete FeatureService following requirement 3.2, using FeatureModel and extending BaseService patterns with proper error handling from src/utils/errorHandler.ts | Restrictions: Must implement interface contract exactly, do not bypass model validation, maintain separation of concerns from data layer | Success: Service implements all interface methods correctly, robust error handling implemented, business logic is well-encapsulated and testable_
- [ ] 7. Add service dependency injection in src/utils/di.ts
- File: src/utils/di.ts (modify existing)
- Register FeatureService in dependency injection container
- Configure service lifetime and dependencies
- Purpose: Enable service injection throughout application
- _Leverage: existing DI configuration in src/utils/di.ts_
- _Requirements: 3.1_
- _Prompt: Role: DevOps Engineer with expertise in dependency injection and IoC containers | Task: Register FeatureService in DI container following requirement 3.1, configuring appropriate lifetime and dependencies using existing patterns from src/utils/di.ts | Restrictions: Must follow existing DI container patterns, do not create circular dependencies, maintain service resolution efficiency | Success: FeatureService is properly registered and resolvable, dependencies are correctly configured, service lifetime is appropriate for use case_
- [ ] 8. Create service unit tests in tests/services/FeatureService.test.ts
- File: tests/services/FeatureService.test.ts
- Write tests for service methods with mocked dependencies
- Test error handling scenarios
- Purpose: Ensure service reliability and proper error handling
- _Leverage: tests/helpers/testUtils.ts, tests/mocks/modelMocks.ts_
- _Requirements: 3.2, 3.3_
- _Prompt: Role: QA Engineer with expertise in service testing and mocking frameworks | Task: Create comprehensive unit tests for FeatureService methods covering requirements 3.2 and 3.3, using mocked dependencies from tests/mocks/modelMocks.ts and test utilities | Restrictions: Must mock all external dependencies, test business logic in isolation, do not test framework code | Success: All service methods tested with proper mocking, error scenarios covered, tests verify business logic correctness and error handling_
- [ ] 4. Create API endpoints
- Design API structure
- _Leverage: src/api/baseApi.ts, src/utils/apiUtils.ts_
- _Requirements: 4.0_
- _Prompt: Role: API Architect specializing in RESTful design and Express.js | Task: Design comprehensive API structure following requirement 4.0, leveraging existing patterns from src/api/baseApi.ts and utilities from src/utils/apiUtils.ts | Restrictions: Must follow REST conventions, maintain API versioning compatibility, do not expose internal data structures directly | Success: API structure is well-designed and documented, follows existing patterns, supports all required operations with proper HTTP methods and status codes_
- [ ] 4.1 Set up routing and middleware
- Configure application routes
- Add authentication middleware
- Set up error handling middleware
- _Leverage: src/middleware/auth.ts, src/middleware/errorHandler.ts_
- _Requirements: 4.1_
- _Prompt: Role: Backend Developer with expertise in Express.js middleware and routing | Task: Configure application routes and middleware following requirement 4.1, integrating authentication from src/middleware/auth.ts and error handling from src/middleware/errorHandler.ts | Restrictions: Must maintain middleware order, do not bypass security middleware, ensure proper error propagation | Success: Routes are properly configured with correct middleware chain, authentication works correctly, errors are handled gracefully throughout the request lifecycle_
- [ ] 4.2 Implement CRUD endpoints
- Create API endpoints
- Add request validation
- Write API integration tests
- _Leverage: src/controllers/BaseController.ts, src/utils/validation.ts_
- _Requirements: 4.2, 4.3_
- _Prompt: Role: Full-stack Developer with expertise in API development and validation | Task: Implement CRUD endpoints following requirements 4.2 and 4.3, extending BaseController patterns and using validation utilities from src/utils/validation.ts | Restrictions: Must validate all inputs, follow existing controller patterns, ensure proper HTTP status codes and responses | Success: All CRUD operations work correctly, request validation prevents invalid data, integration tests pass and cover all endpoints_
- [ ] 5. Add frontend components
- Plan component architecture
- _Leverage: src/components/BaseComponent.tsx, src/styles/theme.ts_
- _Requirements: 5.0_
- _Prompt: Role: Frontend Architect with expertise in React component design and architecture | Task: Plan comprehensive component architecture following requirement 5.0, leveraging base patterns from src/components/BaseComponent.tsx and theme system from src/styles/theme.ts | Restrictions: Must follow existing component patterns, maintain design system consistency, ensure component reusability | Success: Architecture is well-planned and documented, components are properly organized, follows existing patterns and theme system_
- [ ] 5.1 Create base UI components
- Set up component structure
- Implement reusable components
- Add styling and theming
- _Leverage: src/components/BaseComponent.tsx, src/styles/theme.ts_
- _Requirements: 5.1_
- _Prompt: Role: Frontend Developer specializing in React and component architecture | Task: Create reusable UI components following requirement 5.1, extending BaseComponent patterns and using existing theme system from src/styles/theme.ts | Restrictions: Must use existing theme variables, follow component composition patterns, ensure accessibility compliance | Success: Components are reusable and properly themed, follow existing architecture, accessible and responsive_
- [ ] 5.2 Implement feature-specific components
- Create feature components
- Add state management
- Connect to API endpoints
- _Leverage: src/hooks/useApi.ts, src/components/BaseComponent.tsx_
- _Requirements: 5.2, 5.3_
- _Prompt: Role: React Developer with expertise in state management and API integration | Task: Implement feature-specific components following requirements 5.2 and 5.3, using API hooks from src/hooks/useApi.ts and extending BaseComponent patterns | Restrictions: Must use existing state management patterns, handle loading and error states properly, maintain component performance | Success: Components are fully functional with proper state management, API integration works smoothly, user experience is responsive and intuitive_
- [ ] 6. Integration and testing
- Plan integration approach
- _Leverage: src/utils/integrationUtils.ts, tests/helpers/testUtils.ts_
- _Requirements: 6.0_
- _Prompt: Role: Integration Engineer with expertise in system integration and testing strategies | Task: Plan comprehensive integration approach following requirement 6.0, leveraging integration utilities from src/utils/integrationUtils.ts and test helpers | Restrictions: Must consider all system components, ensure proper test coverage, maintain integration test reliability | Success: Integration plan is comprehensive and feasible, all system components work together correctly, integration points are well-tested_
- [ ] 6.1 Write end-to-end tests
- Set up E2E testing framework
- Write user journey tests
- Add test automation
- _Leverage: tests/helpers/testUtils.ts, tests/fixtures/data.ts_
- _Requirements: All_
- _Prompt: Role: QA Automation Engineer with expertise in E2E testing and test frameworks like Cypress or Playwright | Task: Implement comprehensive end-to-end tests covering all requirements, setting up testing framework and user journey tests using test utilities and fixtures | Restrictions: Must test real user workflows, ensure tests are maintainable and reliable, do not test implementation details | Success: E2E tests cover all critical user journeys, tests run reliably in CI/CD pipeline, user experience is validated from end-to-end_
- [ ] 6.2 Final integration and cleanup
- Integrate all components
- Fix any integration issues
- Clean up code and documentation
- _Leverage: src/utils/cleanup.ts, docs/templates/_
- _Requirements: All_
- _Prompt: Role: Senior Developer with expertise in code quality and system integration | Task: Complete final integration of all components and perform comprehensive cleanup covering all requirements, using cleanup utilities and documentation templates | Restrictions: Must not break existing functionality, ensure code quality standards are met, maintain documentation consistency | Success: All components are fully integrated and working together, code is clean and well-documented, system meets all requirements and quality standards_

View File

@@ -0,0 +1,99 @@
# Technology Stack
## Project Type
[Describe what kind of project this is: web application, CLI tool, desktop application, mobile app, library, API service, embedded system, game, etc.]
## Core Technologies
### Primary Language(s)
- **Language**: [e.g., Python 3.11, Go 1.21, TypeScript, Rust, C++]
- **Runtime/Compiler**: [if applicable]
- **Language-specific tools**: [package managers, build tools, etc.]
### Key Dependencies/Libraries
[List the main libraries and frameworks your project depends on]
- **[Library/Framework name]**: [Purpose and version]
- **[Library/Framework name]**: [Purpose and version]
### Application Architecture
[Describe how your application is structured - this could be MVC, event-driven, plugin-based, client-server, standalone, microservices, monolithic, etc.]
### Data Storage (if applicable)
- **Primary storage**: [e.g., PostgreSQL, files, in-memory, cloud storage]
- **Caching**: [e.g., Redis, in-memory, disk cache]
- **Data formats**: [e.g., JSON, Protocol Buffers, XML, binary]
### External Integrations (if applicable)
- **APIs**: [External services you integrate with]
- **Protocols**: [e.g., HTTP/REST, gRPC, WebSocket, TCP/IP]
- **Authentication**: [e.g., OAuth, API keys, certificates]
### Monitoring & Dashboard Technologies (if applicable)
- **Dashboard Framework**: [e.g., React, Vue, vanilla JS, terminal UI]
- **Real-time Communication**: [e.g., WebSocket, Server-Sent Events, polling]
- **Visualization Libraries**: [e.g., Chart.js, D3, terminal graphs]
- **State Management**: [e.g., Redux, Vuex, file system as source of truth]
## Development Environment
### Build & Development Tools
- **Build System**: [e.g., Make, CMake, Gradle, npm scripts, cargo]
- **Package Management**: [e.g., pip, npm, cargo, go mod, apt, brew]
- **Development workflow**: [e.g., hot reload, watch mode, REPL]
### Code Quality Tools
- **Static Analysis**: [Tools for code quality and correctness]
- **Formatting**: [Code style enforcement tools]
- **Testing Framework**: [Unit, integration, and/or end-to-end testing tools]
- **Documentation**: [Documentation generation tools]
### Version Control & Collaboration
- **VCS**: [e.g., Git, Mercurial, SVN]
- **Branching Strategy**: [e.g., Git Flow, GitHub Flow, trunk-based]
- **Code Review Process**: [How code reviews are conducted]
### Dashboard Development (if applicable)
- **Live Reload**: [e.g., Hot module replacement, file watchers]
- **Port Management**: [e.g., Dynamic allocation, configurable ports]
- **Multi-Instance Support**: [e.g., Running multiple dashboards simultaneously]
## Deployment & Distribution (if applicable)
- **Target Platform(s)**: [Where/how the project runs: cloud, on-premise, desktop, mobile, embedded]
- **Distribution Method**: [How users get your software: download, package manager, app store, SaaS]
- **Installation Requirements**: [Prerequisites, system requirements]
- **Update Mechanism**: [How updates are delivered]
## Technical Requirements & Constraints
### Performance Requirements
- [e.g., response time, throughput, memory usage, startup time]
- [Specific benchmarks or targets]
### Compatibility Requirements
- **Platform Support**: [Operating systems, architectures, versions]
- **Dependency Versions**: [Minimum/maximum versions of dependencies]
- **Standards Compliance**: [Industry standards, protocols, specifications]
### Security & Compliance
- **Security Requirements**: [Authentication, encryption, data protection]
- **Compliance Standards**: [GDPR, HIPAA, SOC2, etc. if applicable]
- **Threat Model**: [Key security considerations]
### Scalability & Reliability
- **Expected Load**: [Users, requests, data volume]
- **Availability Requirements**: [Uptime targets, disaster recovery]
- **Growth Projections**: [How the system needs to scale]
## Technical Decisions & Rationale
[Document key architectural and technology choices]
### Decision Log
1. **[Technology/Pattern Choice]**: [Why this was chosen, alternatives considered]
2. **[Architecture Decision]**: [Rationale, trade-offs accepted]
3. **[Tool/Library Selection]**: [Reasoning, evaluation criteria]
## Known Limitations
[Document any technical debt, limitations, or areas for improvement]
- [Limitation 1]: [Impact and potential future solutions]
- [Limitation 2]: [Why it exists and when it might be addressed]

View File

@@ -0,0 +1,64 @@
# User Templates
This directory allows you to create custom templates that override the default Spec Workflow templates.
## How to Use Custom Templates
1. **Create your custom template file** in this directory with the exact same name as the default template you want to override:
- `requirements-template.md` - Override requirements document template
- `design-template.md` - Override design document template
- `tasks-template.md` - Override tasks document template
- `product-template.md` - Override product steering template
- `tech-template.md` - Override tech steering template
- `structure-template.md` - Override structure steering template
2. **Template Loading Priority**:
- The system first checks this `user-templates/` directory
- If a matching template is found here, it will be used
- Otherwise, the default template from `templates/` will be used
## Example Custom Template
To create a custom requirements template:
1. Create a file named `requirements-template.md` in this directory
2. Add your custom structure, for example:
```markdown
# Requirements Document
## Executive Summary
[Your custom section]
## Business Requirements
[Your custom structure]
## Technical Requirements
[Your custom fields]
## Custom Sections
[Add any sections specific to your workflow]
```
## Template Variables
Templates can include placeholders that will be replaced when documents are created:
- `{{projectName}}` - The name of your project
- `{{featureName}}` - The name of the feature being specified
- `{{date}}` - The current date
- `{{author}}` - The document author
## Best Practices
1. **Start from defaults**: Copy a default template from `../templates/` as a starting point
2. **Keep structure consistent**: Maintain similar section headers for tool compatibility
3. **Document changes**: Add comments explaining why sections were added/modified
4. **Version control**: Track your custom templates in version control
5. **Test thoroughly**: Ensure custom templates work with the spec workflow tools
## Notes
- Custom templates are project-specific and not included in the package distribution
- The `templates/` directory contains the default templates which are updated with each version
- Your custom templates in this directory are preserved during updates
- If a custom template has errors, the system will fall back to the default template

View File

@@ -82,14 +82,20 @@ source "$SCRIPT_DIR/common.sh"
eval $(get_feature_paths) eval $(get_feature_paths)
check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1 check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1
# If paths-only mode, output paths and exit # If paths-only mode, output paths and exit (support JSON + paths-only combined)
if $PATHS_ONLY; then if $PATHS_ONLY; then
echo "REPO_ROOT: $REPO_ROOT" if $JSON_MODE; then
echo "BRANCH: $CURRENT_BRANCH" # Minimal JSON paths payload (no validation performed)
echo "FEATURE_DIR: $FEATURE_DIR" printf '{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS":"%s"}\n' \
echo "FEATURE_SPEC: $FEATURE_SPEC" "$REPO_ROOT" "$CURRENT_BRANCH" "$FEATURE_DIR" "$FEATURE_SPEC" "$IMPL_PLAN" "$TASKS"
echo "IMPL_PLAN: $IMPL_PLAN" else
echo "TASKS: $TASKS" echo "REPO_ROOT: $REPO_ROOT"
echo "BRANCH: $CURRENT_BRANCH"
echo "FEATURE_DIR: $FEATURE_DIR"
echo "FEATURE_SPEC: $FEATURE_SPEC"
echo "IMPL_PLAN: $IMPL_PLAN"
echo "TASKS: $TASKS"
fi
exit 0 exit 0
fi fi

View File

@@ -80,7 +80,7 @@ fi
FEATURE_DIR="$SPECS_DIR/$BRANCH_NAME" FEATURE_DIR="$SPECS_DIR/$BRANCH_NAME"
mkdir -p "$FEATURE_DIR" mkdir -p "$FEATURE_DIR"
TEMPLATE="$REPO_ROOT/templates/spec-template.md" TEMPLATE="$REPO_ROOT/.specify/templates/spec-template.md"
SPEC_FILE="$FEATURE_DIR/spec.md" SPEC_FILE="$FEATURE_DIR/spec.md"
if [ -f "$TEMPLATE" ]; then cp "$TEMPLATE" "$SPEC_FILE"; else touch "$SPEC_FILE"; fi if [ -f "$TEMPLATE" ]; then cp "$TEMPLATE" "$SPEC_FILE"; else touch "$SPEC_FILE"; fi

View File

@@ -30,12 +30,12 @@
# #
# 5. Multi-Agent Support # 5. Multi-Agent Support
# - Handles agent-specific file paths and naming conventions # - Handles agent-specific file paths and naming conventions
# - Supports: Claude, Gemini, Copilot, Cursor, Qwen, opencode, Codex, Windsurf # - Supports: Claude, Gemini, Copilot, Cursor, Qwen, opencode, Codex, Windsurf, Kilo Code, Auggie CLI, or Amazon Q Developer CLI
# - Can update single agents or all existing agent files # - Can update single agents or all existing agent files
# - Creates default Claude file if no agent files exist # - Creates default Claude file if no agent files exist
# #
# Usage: ./update-agent-context.sh [agent_type] # Usage: ./update-agent-context.sh [agent_type]
# Agent types: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf # Agent types: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|q
# Leave empty to update all existing agent files # Leave empty to update all existing agent files
set -e set -e
@@ -69,6 +69,7 @@ WINDSURF_FILE="$REPO_ROOT/.windsurf/rules/specify-rules.md"
KILOCODE_FILE="$REPO_ROOT/.kilocode/rules/specify-rules.md" KILOCODE_FILE="$REPO_ROOT/.kilocode/rules/specify-rules.md"
AUGGIE_FILE="$REPO_ROOT/.augment/rules/specify-rules.md" AUGGIE_FILE="$REPO_ROOT/.augment/rules/specify-rules.md"
ROO_FILE="$REPO_ROOT/.roo/rules/specify-rules.md" ROO_FILE="$REPO_ROOT/.roo/rules/specify-rules.md"
Q_FILE="$REPO_ROOT/AGENTS.md"
# Template file # Template file
TEMPLATE_FILE="$REPO_ROOT/.specify/templates/agent-file-template.md" TEMPLATE_FILE="$REPO_ROOT/.specify/templates/agent-file-template.md"
@@ -580,9 +581,12 @@ update_specific_agent() {
roo) roo)
update_agent_file "$ROO_FILE" "Roo Code" update_agent_file "$ROO_FILE" "Roo Code"
;; ;;
q)
update_agent_file "$Q_FILE" "Amazon Q Developer CLI"
;;
*) *)
log_error "Unknown agent type '$agent_type'" log_error "Unknown agent type '$agent_type'"
log_error "Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo" log_error "Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|q"
exit 1 exit 1
;; ;;
esac esac
@@ -642,6 +646,11 @@ update_all_existing_agents() {
found_agent=true found_agent=true
fi fi
if [[ -f "$Q_FILE" ]]; then
update_agent_file "$Q_FILE" "Amazon Q Developer CLI"
found_agent=true
fi
# If no agent files exist, create a default Claude file # If no agent files exist, create a default Claude file
if [[ "$found_agent" == false ]]; then if [[ "$found_agent" == false ]]; then
log_info "No existing agent files found, creating default Claude file..." log_info "No existing agent files found, creating default Claude file..."
@@ -665,7 +674,7 @@ print_summary() {
fi fi
echo echo
log_info "Usage: $0 [claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo]" log_info "Usage: $0 [claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|q]"
} }
#============================================================================== #==============================================================================

View File

@@ -9,7 +9,7 @@
1. Load feature spec from Input path 1. Load feature spec from Input path
→ If not found: ERROR "No feature spec at {path}" → If not found: ERROR "No feature spec at {path}"
2. Fill Technical Context (scan for NEEDS CLARIFICATION) 2. Fill Technical Context (scan for NEEDS CLARIFICATION)
→ Detect Project Type from context (web=frontend+backend, mobile=app+api) → Detect Project Type from file system structure or context (web=frontend+backend, mobile=app+api)
→ Set Structure Decision based on project type → Set Structure Decision based on project type
3. Fill the Constitution Check section based on the content of the constitution document. 3. Fill the Constitution Check section based on the content of the constitution document.
4. Evaluate Constitution Check section below 4. Evaluate Constitution Check section below
@@ -18,7 +18,7 @@
→ Update Progress Tracking: Initial Constitution Check → Update Progress Tracking: Initial Constitution Check
5. Execute Phase 0 → research.md 5. Execute Phase 0 → research.md
→ If NEEDS CLARIFICATION remain: ERROR "Resolve unknowns" → If NEEDS CLARIFICATION remain: ERROR "Resolve unknowns"
6. Execute Phase 1 → contracts, data-model.md, quickstart.md, agent-specific template file (e.g., `CLAUDE.md` for Claude Code, `.github/copilot-instructions.md` for GitHub Copilot, `GEMINI.md` for Gemini CLI, `QWEN.md` for Qwen Code or `AGENTS.md` for opencode). 6. Execute Phase 1 → contracts, data-model.md, quickstart.md, agent-specific template file (e.g., `CLAUDE.md` for Claude Code, `.github/copilot-instructions.md` for GitHub Copilot, `GEMINI.md` for Gemini CLI, `QWEN.md` for Qwen Code, or `AGENTS.md` for all other agents).
7. Re-evaluate Constitution Check section 7. Re-evaluate Constitution Check section
→ If new violations: Refactor design, return to Phase 1 → If new violations: Refactor design, return to Phase 1
→ Update Progress Tracking: Post-Design Constitution Check → Update Progress Tracking: Post-Design Constitution Check
@@ -63,8 +63,14 @@ specs/[###-feature]/
``` ```
### Source Code (repository root) ### Source Code (repository root)
<!--
ACTION REQUIRED: Replace the placeholder tree below with the concrete layout
for this feature. Delete unused options and expand the chosen structure with
real paths (e.g., apps/admin, packages/something). The delivered plan must
not include Option labels.
-->
``` ```
# Option 1: Single project (DEFAULT) # [REMOVE IF UNUSED] Option 1: Single project (DEFAULT)
src/ src/
├── models/ ├── models/
├── services/ ├── services/
@@ -76,7 +82,7 @@ tests/
├── integration/ ├── integration/
└── unit/ └── unit/
# Option 2: Web application (when "frontend" + "backend" detected) # [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected)
backend/ backend/
├── src/ ├── src/
│ ├── models/ │ ├── models/
@@ -91,15 +97,16 @@ frontend/
│ └── services/ │ └── services/
└── tests/ └── tests/
# Option 3: Mobile + API (when "iOS/Android" detected) # [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected)
api/ api/
└── [same as backend above] └── [same as backend above]
ios/ or android/ ios/ or android/
└── [platform-specific structure] └── [platform-specific structure: feature modules, UI flows, platform tests]
``` ```
**Structure Decision**: [DEFAULT to Option 1 unless Technical Context indicates web/mobile app] **Structure Decision**: [Document the selected structure and reference the real
directories captured above]
## Phase 0: Outline & Research ## Phase 0: Outline & Research
1. **Extract unknowns from Technical Context** above: 1. **Extract unknowns from Technical Context** above:
@@ -145,7 +152,7 @@ ios/ or android/
- Quickstart test = story validation steps - Quickstart test = story validation steps
5. **Update agent file incrementally** (O(1) operation): 5. **Update agent file incrementally** (O(1) operation):
- Run `.specify/scripts/bash/update-agent-context.sh codex` - Run `.specify/scripts/bash/update-agent-context.sh opencode`
**IMPORTANT**: Execute it exactly as specified above. Do not add or remove any arguments. **IMPORTANT**: Execute it exactly as specified above. Do not add or remove any arguments.
- If exists: Add only NEW tech from current plan - If exists: Add only NEW tech from current plan
- Preserve manual additions between markers - Preserve manual additions between markers

8100
AGENTS.md

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +1,3 @@
legacy-peer-deps=true legacy-peer-deps=true
enable-pre-post-scripts=true enable-pre-post-scripts=true
shared-workspace-lockfile=false

9297
apps/backend/cloudflare-env.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
{ {
"name": "", "name": "backend",
"version": "1.0.0", "version": "1.0.0",
"description": "Website template for Payload", "private": true,
"description": "Enchun Website use PayloadCMS",
"license": "MIT", "license": "MIT",
"type": "module", "type": "module",
"scripts": { "scripts": {
@@ -22,18 +23,21 @@
"test:int": "cross-env NODE_OPTIONS=--no-deprecation vitest run --config ./vitest.config.mts" "test:int": "cross-env NODE_OPTIONS=--no-deprecation vitest run --config ./vitest.config.mts"
}, },
"dependencies": { "dependencies": {
"@payloadcms/admin-bar": "3.56.0", "@opennextjs/cloudflare": "^1.10.1",
"@payloadcms/db-mongodb": "3.56.0", "@payloadcms/admin-bar": "3.59.1",
"@payloadcms/live-preview-react": "3.56.0", "@payloadcms/db-mongodb": "3.59.1",
"@payloadcms/next": "3.56.0", "@payloadcms/email-resend": "3.59.1",
"@payloadcms/payload-cloud": "3.56.0", "@payloadcms/live-preview-react": "3.59.1",
"@payloadcms/plugin-form-builder": "3.56.0", "@payloadcms/next": "3.59.1",
"@payloadcms/plugin-nested-docs": "3.56.0", "@payloadcms/payload-cloud": "3.59.1",
"@payloadcms/plugin-redirects": "3.56.0", "@payloadcms/plugin-form-builder": "3.59.1",
"@payloadcms/plugin-search": "3.56.0", "@payloadcms/plugin-nested-docs": "3.59.1",
"@payloadcms/plugin-seo": "3.56.0", "@payloadcms/plugin-redirects": "3.59.1",
"@payloadcms/richtext-lexical": "3.56.0", "@payloadcms/plugin-search": "3.59.1",
"@payloadcms/ui": "3.56.0", "@payloadcms/plugin-seo": "3.59.1",
"@payloadcms/richtext-lexical": "3.59.1",
"@payloadcms/storage-s3": "3.59.1",
"@payloadcms/ui": "3.59.1",
"@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-label": "^2.0.2", "@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-select": "^2.0.0", "@radix-ui/react-select": "^2.0.0",
@@ -47,14 +51,15 @@
"lucide-react": "^0.378.0", "lucide-react": "^0.378.0",
"next": "15.4.4", "next": "15.4.4",
"next-sitemap": "^4.2.3", "next-sitemap": "^4.2.3",
"payload": "3.56.0", "payload": "3.59.1",
"prism-react-renderer": "^2.3.1", "prism-react-renderer": "^2.3.1",
"react": "19.1.0", "react": "19.1.0",
"react-dom": "19.1.0", "react-dom": "19.1.0",
"react-hook-form": "7.45.4", "react-hook-form": "7.45.4",
"sharp": "0.34.2", "sharp": "0.34.2",
"tailwind-merge": "^2.3.0", "tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7" "tailwindcss-animate": "^1.0.7",
"@enchun/shared": "workspace:*"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3.2.0", "@eslint/eslintrc": "^3.2.0",
@@ -83,12 +88,5 @@
"engines": { "engines": {
"node": "^18.20.2 || >=20.9.0", "node": "^18.20.2 || >=20.9.0",
"pnpm": "^9 || ^10" "pnpm": "^9 || ^10"
},
"pnpm": {
"onlyBuiltDependencies": [
"sharp",
"esbuild",
"unrs-resolver"
]
} }
} }

14211
apps/backend/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -22,9 +22,24 @@ export async function Footer() {
<div className="flex flex-col-reverse items-start md:flex-row gap-4 md:items-center"> <div className="flex flex-col-reverse items-start md:flex-row gap-4 md:items-center">
<ThemeSelector /> <ThemeSelector />
<nav className="flex flex-col md:flex-row gap-4"> <nav className="flex flex-col md:flex-row gap-6">
{navItems.map(({ link }, i) => { {navItems.map(({ link, childNavItems }, i) => {
return <CMSLink className="text-white" key={i} {...link} /> const hasChildren = Array.isArray(childNavItems) && childNavItems.length > 0
return (
<div className="flex flex-col gap-2" key={i}>
<CMSLink className="text-white font-medium" {...link} />
{hasChildren ? (
<ul className="ml-2 flex flex-col gap-2 text-sm text-white/80">
{childNavItems?.map(({ link: childLink }, childIndex) => (
<li key={childIndex}>
<CMSLink className="hover:text-white transition" {...childLink} />
</li>
))}
</ul>
) : null}
</div>
)
})} })}
</nav> </nav>
</div> </div>

View File

@@ -1,9 +1,9 @@
'use client' 'use client'
import { Header } from '@/payload-types' import { Footer as FooterGlobal } from '@/payload-types'
import { RowLabelProps, useRowLabel } from '@payloadcms/ui' import { RowLabelProps, useRowLabel } from '@payloadcms/ui'
export const RowLabel: React.FC<RowLabelProps> = () => { export const RowLabel: React.FC<RowLabelProps> = () => {
const data = useRowLabel<NonNullable<Header['navItems']>[number]>() const data = useRowLabel<NonNullable<FooterGlobal['navItems']>[number]>()
const label = data?.data?.link?.label const label = data?.data?.link?.label
? `Nav item ${data.rowNumber !== undefined ? data.rowNumber + 1 : ''}: ${data?.data?.link?.label}` ? `Nav item ${data.rowNumber !== undefined ? data.rowNumber + 1 : ''}: ${data?.data?.link?.label}`

View File

@@ -16,6 +16,20 @@ export const Footer: GlobalConfig = {
link({ link({
appearances: false, appearances: false,
}), }),
{
name: 'childNavItems',
label: 'Nested links',
type: 'array',
fields: [
link({
appearances: false,
}),
],
maxRows: 8,
admin: {
initCollapsed: true,
},
},
], ],
maxRows: 6, maxRows: 6,
admin: { admin: {

View File

@@ -7,6 +7,7 @@ import { getPayload } from 'payload'
import { draftMode } from 'next/headers' import { draftMode } from 'next/headers'
import React, { cache } from 'react' import React, { cache } from 'react'
import RichText from '@/components/RichText' import RichText from '@/components/RichText'
import type { DefaultTypedEditorState } from '@payloadcms/richtext-lexical'
import type { Post } from '@/payload-types' import type { Post } from '@/payload-types'
@@ -62,7 +63,11 @@ export default async function Post({ params: paramsPromise }: Args) {
<div className="flex flex-col items-center gap-4 pt-8"> <div className="flex flex-col items-center gap-4 pt-8">
<div className="container"> <div className="container">
<RichText className="max-w-[48rem] mx-auto" data={post.content} enableGutter={false} /> <RichText
className="max-w-[48rem] mx-auto"
data={post.content as DefaultTypedEditorState}
enableGutter={false}
/>
{post.relatedPosts && post.relatedPosts.length > 0 && ( {post.relatedPosts && post.relatedPosts.length > 0 && (
<RelatedPosts <RelatedPosts
className="mt-12 max-w-[52rem] lg:grid lg:grid-cols-subgrid col-start-1 col-span-3 grid-rows-[2fr]" className="mt-12 max-w-[52rem] lg:grid lg:grid-cols-subgrid col-start-1 col-span-3 grid-rows-[2fr]"

View File

@@ -23,49 +23,33 @@ import { RowLabel as RowLabel_ec255a65fa6fa8d1faeb09cf35284224 } from '@/Header/
import { RowLabel as RowLabel_1f6ff6ff633e3695d348f4f3c58f1466 } from '@/Footer/RowLabel' import { RowLabel as RowLabel_1f6ff6ff633e3695d348f4f3c58f1466 } from '@/Footer/RowLabel'
import { default as default_1a7510af427896d367a49dbf838d2de6 } from '@/components/BeforeDashboard' import { default as default_1a7510af427896d367a49dbf838d2de6 } from '@/components/BeforeDashboard'
import { default as default_8a7ab0eb7ab5c511aba12e68480bfe5e } from '@/components/BeforeLogin' import { default as default_8a7ab0eb7ab5c511aba12e68480bfe5e } from '@/components/BeforeLogin'
import { S3ClientUploadHandler as S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24 } from '@payloadcms/storage-s3/client'
export const importMap = { export const importMap = {
'@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell': "@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell": RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e,
RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e, "@payloadcms/richtext-lexical/rsc#RscEntryLexicalField": RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e,
'@payloadcms/richtext-lexical/rsc#RscEntryLexicalField': "@payloadcms/richtext-lexical/rsc#LexicalDiffComponent": LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e,
RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e, "@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient": InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/rsc#LexicalDiffComponent': "@payloadcms/richtext-lexical/client#FixedToolbarFeatureClient": FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e, "@payloadcms/richtext-lexical/client#HeadingFeatureClient": HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient': "@payloadcms/richtext-lexical/client#ParagraphFeatureClient": ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, "@payloadcms/richtext-lexical/client#UnderlineFeatureClient": UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#FixedToolbarFeatureClient': "@payloadcms/richtext-lexical/client#BoldFeatureClient": BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, "@payloadcms/richtext-lexical/client#ItalicFeatureClient": ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#HeadingFeatureClient': "@payloadcms/richtext-lexical/client#LinkFeatureClient": LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, "@payloadcms/plugin-seo/client#OverviewComponent": OverviewComponent_a8a977ebc872c5d5ea7ee689724c0860,
'@payloadcms/richtext-lexical/client#ParagraphFeatureClient': "@payloadcms/plugin-seo/client#MetaTitleComponent": MetaTitleComponent_a8a977ebc872c5d5ea7ee689724c0860,
ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, "@payloadcms/plugin-seo/client#MetaImageComponent": MetaImageComponent_a8a977ebc872c5d5ea7ee689724c0860,
'@payloadcms/richtext-lexical/client#UnderlineFeatureClient': "@payloadcms/plugin-seo/client#MetaDescriptionComponent": MetaDescriptionComponent_a8a977ebc872c5d5ea7ee689724c0860,
UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, "@payloadcms/plugin-seo/client#PreviewComponent": PreviewComponent_a8a977ebc872c5d5ea7ee689724c0860,
'@payloadcms/richtext-lexical/client#BoldFeatureClient': "@/fields/slug/SlugComponent#SlugComponent": SlugComponent_92cc057d0a2abb4f6cf0307edf59f986,
BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, "@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient": HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#ItalicFeatureClient': "@payloadcms/richtext-lexical/client#BlocksFeatureClient": BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, "@payloadcms/plugin-search/client#LinkToDoc": LinkToDoc_aead06e4cbf6b2620c5c51c9ab283634,
'@payloadcms/richtext-lexical/client#LinkFeatureClient': "@payloadcms/plugin-search/client#ReindexButton": ReindexButton_aead06e4cbf6b2620c5c51c9ab283634,
LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, "@/Header/RowLabel#RowLabel": RowLabel_ec255a65fa6fa8d1faeb09cf35284224,
'@payloadcms/plugin-seo/client#OverviewComponent': "@/Footer/RowLabel#RowLabel": RowLabel_1f6ff6ff633e3695d348f4f3c58f1466,
OverviewComponent_a8a977ebc872c5d5ea7ee689724c0860, "@/components/BeforeDashboard#default": default_1a7510af427896d367a49dbf838d2de6,
'@payloadcms/plugin-seo/client#MetaTitleComponent': "@/components/BeforeLogin#default": default_8a7ab0eb7ab5c511aba12e68480bfe5e,
MetaTitleComponent_a8a977ebc872c5d5ea7ee689724c0860, "@payloadcms/storage-s3/client#S3ClientUploadHandler": S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24
'@payloadcms/plugin-seo/client#MetaImageComponent':
MetaImageComponent_a8a977ebc872c5d5ea7ee689724c0860,
'@payloadcms/plugin-seo/client#MetaDescriptionComponent':
MetaDescriptionComponent_a8a977ebc872c5d5ea7ee689724c0860,
'@payloadcms/plugin-seo/client#PreviewComponent':
PreviewComponent_a8a977ebc872c5d5ea7ee689724c0860,
'@/fields/slug/SlugComponent#SlugComponent': SlugComponent_92cc057d0a2abb4f6cf0307edf59f986,
'@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient':
HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/richtext-lexical/client#BlocksFeatureClient':
BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
'@payloadcms/plugin-search/client#LinkToDoc': LinkToDoc_aead06e4cbf6b2620c5c51c9ab283634,
'@payloadcms/plugin-search/client#ReindexButton': ReindexButton_aead06e4cbf6b2620c5c51c9ab283634,
'@/Header/RowLabel#RowLabel': RowLabel_ec255a65fa6fa8d1faeb09cf35284224,
'@/Footer/RowLabel#RowLabel': RowLabel_1f6ff6ff633e3695d348f4f3c58f1466,
'@/components/BeforeDashboard#default': default_1a7510af427896d367a49dbf838d2de6,
'@/components/BeforeLogin#default': default_8a7ab0eb7ab5c511aba12e68480bfe5e,
} }

View File

@@ -4,6 +4,7 @@ import configPromise from '@payload-config'
import { getPayload } from 'payload' import { getPayload } from 'payload'
import React from 'react' import React from 'react'
import RichText from '@/components/RichText' import RichText from '@/components/RichText'
import type { DefaultTypedEditorState } from '@payloadcms/richtext-lexical'
import { CollectionArchive } from '@/components/CollectionArchive' import { CollectionArchive } from '@/components/CollectionArchive'
@@ -56,7 +57,11 @@ export const ArchiveBlock: React.FC<
<div className="my-16" id={`block-${id}`}> <div className="my-16" id={`block-${id}`}>
{introContent && ( {introContent && (
<div className="container mb-16"> <div className="container mb-16">
<RichText className="ms-0 max-w-[48rem]" data={introContent} enableGutter={false} /> <RichText
className="ms-0 max-w-[48rem]"
data={introContent as DefaultTypedEditorState}
enableGutter={false}
/>
</div> </div>
)} )}
<CollectionArchive posts={posts} /> <CollectionArchive posts={posts} />

View File

@@ -3,6 +3,7 @@ import type { BannerBlock as BannerBlockProps } from 'src/payload-types'
import { cn } from '@/utilities/ui' import { cn } from '@/utilities/ui'
import React from 'react' import React from 'react'
import RichText from '@/components/RichText' import RichText from '@/components/RichText'
import type { DefaultTypedEditorState } from '@payloadcms/richtext-lexical'
type Props = { type Props = {
className?: string className?: string
@@ -19,7 +20,11 @@ export const BannerBlock: React.FC<Props> = ({ className, content, style }) => {
'border-warning bg-warning/30': style === 'warning', 'border-warning bg-warning/30': style === 'warning',
})} })}
> >
<RichText data={content} enableGutter={false} enableProse={false} /> <RichText
data={content as DefaultTypedEditorState}
enableGutter={false}
enableProse={false}
/>
</div> </div>
</div> </div>
) )

View File

@@ -3,6 +3,7 @@ import React from 'react'
import type { CallToActionBlock as CTABlockProps } from '@/payload-types' import type { CallToActionBlock as CTABlockProps } from '@/payload-types'
import RichText from '@/components/RichText' import RichText from '@/components/RichText'
import type { DefaultTypedEditorState } from '@payloadcms/richtext-lexical'
import { CMSLink } from '@/components/Link' import { CMSLink } from '@/components/Link'
export const CallToActionBlock: React.FC<CTABlockProps> = ({ links, richText }) => { export const CallToActionBlock: React.FC<CTABlockProps> = ({ links, richText }) => {
@@ -10,7 +11,13 @@ export const CallToActionBlock: React.FC<CTABlockProps> = ({ links, richText })
<div className="container"> <div className="container">
<div className="bg-card rounded border-border border p-4 flex flex-col gap-8 md:flex-row md:justify-between md:items-center"> <div className="bg-card rounded border-border border p-4 flex flex-col gap-8 md:flex-row md:justify-between md:items-center">
<div className="max-w-[48rem] flex items-center"> <div className="max-w-[48rem] flex items-center">
{richText && <RichText className="mb-0" data={richText} enableGutter={false} />} {richText && (
<RichText
className="mb-0"
data={richText as DefaultTypedEditorState}
enableGutter={false}
/>
)}
</div> </div>
<div className="flex flex-col gap-8"> <div className="flex flex-col gap-8">
{(links || []).map(({ link }, i) => { {(links || []).map(({ link }, i) => {

View File

@@ -1,6 +1,7 @@
import { cn } from '@/utilities/ui' import { cn } from '@/utilities/ui'
import React from 'react' import React from 'react'
import RichText from '@/components/RichText' import RichText from '@/components/RichText'
import type { DefaultTypedEditorState } from '@payloadcms/richtext-lexical'
import type { ContentBlock as ContentBlockProps } from '@/payload-types' import type { ContentBlock as ContentBlockProps } from '@/payload-types'
@@ -31,7 +32,9 @@ export const ContentBlock: React.FC<ContentBlockProps> = (props) => {
})} })}
key={index} key={index}
> >
{richText && <RichText data={richText} enableGutter={false} />} {richText && (
<RichText data={richText as DefaultTypedEditorState} enableGutter={false} />
)}
{enableLink && <CMSLink {...link} />} {enableLink && <CMSLink {...link} />}
</div> </div>

View File

@@ -74,7 +74,7 @@ export const FormBlock: React.FC<
method: 'POST', method: 'POST',
}) })
const res = await req.json() const res = (await req.json()) as any
clearTimeout(loadingTimerID) clearTimeout(loadingTimerID)
@@ -121,7 +121,7 @@ export const FormBlock: React.FC<
<div className="p-4 lg:p-6 border border-border rounded-[0.8rem]"> <div className="p-4 lg:p-6 border border-border rounded-[0.8rem]">
<FormProvider {...formMethods}> <FormProvider {...formMethods}>
{!isLoading && hasSubmitted && confirmationType === 'message' && ( {!isLoading && hasSubmitted && confirmationType === 'message' && (
<RichText data={confirmationMessage} /> <RichText data={confirmationMessage as DefaultTypedEditorState} />
)} )}
{isLoading && !hasSubmitted && <p>Loading, please wait...</p>} {isLoading && !hasSubmitted && <p>Loading, please wait...</p>}
{error && <div>{`${error.status || '500'}: ${error.message || ''}`}</div>} {error && <div>{`${error.status || '500'}: ${error.message || ''}`}</div>}

View File

@@ -3,6 +3,7 @@ import type { StaticImageData } from 'next/image'
import { cn } from '@/utilities/ui' import { cn } from '@/utilities/ui'
import React from 'react' import React from 'react'
import RichText from '@/components/RichText' import RichText from '@/components/RichText'
import type { DefaultTypedEditorState } from '@payloadcms/richtext-lexical'
import type { MediaBlock as MediaBlockProps } from '@/payload-types' import type { MediaBlock as MediaBlockProps } from '@/payload-types'
@@ -59,7 +60,7 @@ export const MediaBlock: React.FC<Props> = (props) => {
captionClassName, captionClassName,
)} )}
> >
<RichText data={caption} enableGutter={false} /> <RichText data={caption as DefaultTypedEditorState} enableGutter={false} />
</div> </div>
)} )}
</div> </div>

View File

@@ -7,6 +7,7 @@ import type { Page } from '@/payload-types'
import { CMSLink } from '@/components/Link' import { CMSLink } from '@/components/Link'
import { Media } from '@/components/Media' import { Media } from '@/components/Media'
import RichText from '@/components/RichText' import RichText from '@/components/RichText'
import type { DefaultTypedEditorState } from '@payloadcms/richtext-lexical'
export const HighImpactHero: React.FC<Page['hero']> = ({ links, media, richText }) => { export const HighImpactHero: React.FC<Page['hero']> = ({ links, media, richText }) => {
const { setHeaderTheme } = useHeaderTheme() const { setHeaderTheme } = useHeaderTheme()
@@ -22,7 +23,13 @@ export const HighImpactHero: React.FC<Page['hero']> = ({ links, media, richText
> >
<div className="container mb-8 z-10 relative flex items-center justify-center"> <div className="container mb-8 z-10 relative flex items-center justify-center">
<div className="max-w-[36.5rem] md:text-center"> <div className="max-w-[36.5rem] md:text-center">
{richText && <RichText className="mb-6" data={richText} enableGutter={false} />} {richText && (
<RichText
className="mb-6"
data={richText as DefaultTypedEditorState}
enableGutter={false}
/>
)}
{Array.isArray(links) && links.length > 0 && ( {Array.isArray(links) && links.length > 0 && (
<ul className="flex md:justify-center gap-4"> <ul className="flex md:justify-center gap-4">
{links.map(({ link }, i) => { {links.map(({ link }, i) => {

View File

@@ -3,6 +3,7 @@ import React from 'react'
import type { Page } from '@/payload-types' import type { Page } from '@/payload-types'
import RichText from '@/components/RichText' import RichText from '@/components/RichText'
import type { DefaultTypedEditorState } from '@payloadcms/richtext-lexical'
type LowImpactHeroType = type LowImpactHeroType =
| { | {
@@ -18,7 +19,10 @@ export const LowImpactHero: React.FC<LowImpactHeroType> = ({ children, richText
return ( return (
<div className="container mt-16"> <div className="container mt-16">
<div className="max-w-[48rem]"> <div className="max-w-[48rem]">
{children || (richText && <RichText data={richText} enableGutter={false} />)} {children ||
(richText && (
<RichText data={richText as DefaultTypedEditorState} enableGutter={false} />
))}
</div> </div>
</div> </div>
) )

View File

@@ -5,12 +5,19 @@ import type { Page } from '@/payload-types'
import { CMSLink } from '@/components/Link' import { CMSLink } from '@/components/Link'
import { Media } from '@/components/Media' import { Media } from '@/components/Media'
import RichText from '@/components/RichText' import RichText from '@/components/RichText'
import type { DefaultTypedEditorState } from '@payloadcms/richtext-lexical'
export const MediumImpactHero: React.FC<Page['hero']> = ({ links, media, richText }) => { export const MediumImpactHero: React.FC<Page['hero']> = ({ links, media, richText }) => {
return ( return (
<div className=""> <div className="">
<div className="container mb-8"> <div className="container mb-8">
{richText && <RichText className="mb-6" data={richText} enableGutter={false} />} {richText && (
<RichText
className="mb-6"
data={richText as DefaultTypedEditorState}
enableGutter={false}
/>
)}
{Array.isArray(links) && links.length > 0 && ( {Array.isArray(links) && links.length > 0 && (
<ul className="flex gap-4"> <ul className="flex gap-4">
@@ -35,7 +42,7 @@ export const MediumImpactHero: React.FC<Page['hero']> = ({ links, media, richTex
/> />
{media?.caption && ( {media?.caption && (
<div className="mt-3"> <div className="mt-3">
<RichText data={media.caption} enableGutter={false} /> <RichText data={media.caption as DefaultTypedEditorState} enableGutter={false} />
</div> </div>
)} )}
</div> </div>

View File

@@ -154,7 +154,7 @@ export interface Page {
root: { root: {
type: string; type: string;
children: { children: {
type: any; type: string;
version: number; version: number;
[k: string]: unknown; [k: string]: unknown;
}[]; }[];
@@ -219,7 +219,7 @@ export interface Post {
root: { root: {
type: string; type: string;
children: { children: {
type: any; type: string;
version: number; version: number;
[k: string]: unknown; [k: string]: unknown;
}[]; }[];
@@ -265,7 +265,7 @@ export interface Media {
root: { root: {
type: string; type: string;
children: { children: {
type: any; type: string;
version: number; version: number;
[k: string]: unknown; [k: string]: unknown;
}[]; }[];
@@ -401,7 +401,7 @@ export interface CallToActionBlock {
root: { root: {
type: string; type: string;
children: { children: {
type: any; type: string;
version: number; version: number;
[k: string]: unknown; [k: string]: unknown;
}[]; }[];
@@ -452,7 +452,7 @@ export interface ContentBlock {
root: { root: {
type: string; type: string;
children: { children: {
type: any; type: string;
version: number; version: number;
[k: string]: unknown; [k: string]: unknown;
}[]; }[];
@@ -509,7 +509,7 @@ export interface ArchiveBlock {
root: { root: {
type: string; type: string;
children: { children: {
type: any; type: string;
version: number; version: number;
[k: string]: unknown; [k: string]: unknown;
}[]; }[];
@@ -545,7 +545,7 @@ export interface FormBlock {
root: { root: {
type: string; type: string;
children: { children: {
type: any; type: string;
version: number; version: number;
[k: string]: unknown; [k: string]: unknown;
}[]; }[];
@@ -602,7 +602,7 @@ export interface Form {
root: { root: {
type: string; type: string;
children: { children: {
type: any; type: string;
version: number; version: number;
[k: string]: unknown; [k: string]: unknown;
}[]; }[];
@@ -685,7 +685,7 @@ export interface Form {
root: { root: {
type: string; type: string;
children: { children: {
type: any; type: string;
version: number; version: number;
[k: string]: unknown; [k: string]: unknown;
}[]; }[];
@@ -717,7 +717,7 @@ export interface Form {
root: { root: {
type: string; type: string;
children: { children: {
type: any; type: string;
version: number; version: number;
[k: string]: unknown; [k: string]: unknown;
}[]; }[];
@@ -1598,6 +1598,26 @@ export interface Footer {
url?: string | null; url?: string | null;
label: string; label: string;
}; };
childNavItems?:
| {
link: {
type?: ('reference' | 'custom') | null;
newTab?: boolean | null;
reference?:
| ({
relationTo: 'pages';
value: string | Page;
} | null)
| ({
relationTo: 'posts';
value: string | Post;
} | null);
url?: string | null;
label: string;
};
id?: string | null;
}[]
| null;
id?: string | null; id?: string | null;
}[] }[]
| null; | null;
@@ -1644,6 +1664,20 @@ export interface FooterSelect<T extends boolean = true> {
url?: T; url?: T;
label?: T; label?: T;
}; };
childNavItems?:
| T
| {
link?:
| T
| {
type?: T;
newTab?: T;
reference?: T;
url?: T;
label?: T;
};
id?: T;
};
id?: T; id?: T;
}; };
updatedAt?: T; updatedAt?: T;
@@ -1682,7 +1716,7 @@ export interface BannerBlock {
root: { root: {
type: string; type: string;
children: { children: {
type: any; type: string;
version: number; version: number;
[k: string]: unknown; [k: string]: unknown;
}[]; }[];

View File

@@ -1,11 +1,11 @@
// storage-adapter-import-placeholder // storage-adapter-import-placeholder
import { mongooseAdapter } from '@payloadcms/db-mongodb' import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { s3Storage } from '@payloadcms/storage-s3'
import { resendAdapter } from '@payloadcms/email-resend'
import sharp from 'sharp' // sharp-import import sharp from 'sharp' // sharp-import
import path from 'path' import path from 'path'
import { buildConfig, PayloadRequest } from 'payload' import { buildConfig, PayloadRequest } from 'payload'
import { fileURLToPath } from 'url' import { fileURLToPath } from 'url'
import { Categories } from './collections/Categories' import { Categories } from './collections/Categories'
import { Media } from './collections/Media' import { Media } from './collections/Media'
import { Pages } from './collections/Pages' import { Pages } from './collections/Pages'
@@ -63,11 +63,34 @@ export default buildConfig({
url: process.env.DATABASE_URI || '', url: process.env.DATABASE_URI || '',
}), }),
collections: [Pages, Posts, Media, Categories, Users], collections: [Pages, Posts, Media, Categories, Users],
cors: [getServerSideURL()].filter(Boolean), cors: [
getServerSideURL(),
'http://localhost:4321', // Astro dev server
'http://localhost:8788', // Wrangler Pages dev server
].filter(Boolean),
globals: [Header, Footer], globals: [Header, Footer],
email: resendAdapter({
defaultFromAddress: 'dev@resend.com',
defaultFromName: '恩群數位行銷',
apiKey: process.env.RESEND_API_KEY || '',
}),
plugins: [ plugins: [
...plugins, ...plugins,
// storage-adapter-placeholder s3Storage({
collections: {
media: true,
},
bucket: process.env.R2_BUCKET!,
config: {
endpoint: `https://${process.env.R2_ACCOUNT_ID!}.r2.cloudflarestorage.com`,
credentials: {
accessKeyId: process.env.R2_ACCESS_KEY_ID!,
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
},
region: 'auto',
// ... Other S3 configuration
},
}),
], ],
secret: process.env.PAYLOAD_SECRET, secret: process.env.PAYLOAD_SECRET,
sharp, sharp,

View File

@@ -0,0 +1 @@
export default new Map();

View File

@@ -0,0 +1 @@
export default new Map();

View File

@@ -0,0 +1 @@
[["Map",1,2],"meta::meta",["Map",3,4,5,6],"astro-version","5.14.1","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"server\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"index.js\",\"redirects\":false,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":true,\"port\":4321,\"streaming\":true,\"allowedHosts\":[]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[],\"remotePatterns\":[],\"responsiveStyles\":false},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":{\"type\":\"shiki\",\"excludeLangs\":[\"math\"]},\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"headingIdCompat\":false,\"preserveScriptOrder\":false,\"liveContentCollections\":false,\"csp\":false,\"staticImportMetaEnv\":false,\"chromeDevtoolsWorkspace\":false,\"failOnPrerenderConflict\":false},\"legacy\":{\"collections\":false},\"session\":{\"driver\":\"cloudflare-kv-binding\",\"options\":{\"binding\":\"SESSION\"}}}"]

View File

@@ -1,5 +1,5 @@
{ {
"_variables": { "_variables": {
"lastUpdateCheck": 1758741038303 "lastUpdateCheck": 1760082709773
} }
} }

View File

@@ -1 +0,0 @@
/// <reference types="astro/client" />

View File

@@ -0,0 +1,8 @@
# Environment variables reference
# - .env.local: Used by Astro dev (pnpm dev) - use PUBLIC_ prefix for client-side vars
# - dev.vars: Used by Wrangler Pages dev (pnpm dev:pages)
# - Production: Variables set via Cloudflare dashboard
# Payload CMS API Configuration
PUBLIC_PAYLOAD_CMS_URL=https://enchun-admin.anlstudio.cc
PAYLOAD_CMS_API_KEY=your_api_key_here

View File

@@ -0,0 +1,72 @@
# Spec Workflow MCP Server Configuration File
# ============================================
#
# This is an example configuration file for the Spec Workflow MCP Server.
# Copy this file to 'config.toml' in the same directory to use it.
#
# Configuration Precedence:
# 1. Command-line arguments (highest priority)
# 2. Config file settings
# 3. Built-in defaults (lowest priority)
#
# All settings are optional. Uncomment and modify as needed.
# Please note that not all MCP clients will support loading this config file due to the nature of where they are running from.
# Project directory path
# The root directory of your project where spec files are located.
# Note: You may have to use double slashes (\\) instead of single slashes (/) on Windows or for certain clients.
# Supports tilde (~) expansion for home directory.
# Default: current working directory
# projectDir = "."
# projectDir = "~/my-project"
# projectDir = "/absolute/path/to/project"
# Dashboard port
# The port number for the web dashboard.
# Must be between 1024 and 65535.
# Default: ephemeral port (automatically assigned)
# port = 3000
# Auto-start dashboard
# Automatically launch the dashboard when the MCP server starts.
# The dashboard will open in your default browser.
# Default: false
# autoStartDashboard = false
# Dashboard-only mode
# Run only the web dashboard without the MCP server.
# Useful for standalone dashboard usage.
# Default: false
# dashboardOnly = false
# Language
# Set the interface language for internationalization (i18n).
# Available languages depend on your installation.
# Common values: "en" (English), "ja" (Japanese), etc.
# Default: system language or "en"
# lang = "en"
# Example configurations:
# =====================
# Example 1: Development setup with auto-started dashboard
# ----------------------------------------------------------
# projectDir = "~/dev/my-project"
# autoStartDashboard = true
# port = 3456
# Example 2: Production MCP server without dashboard
# ---------------------------------------------------
# projectDir = "/var/projects/production"
# autoStartDashboard = false
# Example 3: Dashboard-only mode for viewing specs
# -------------------------------------------------
# projectDir = "."
# dashboardOnly = true
# port = 8080
# Example 4: Japanese language interface
# ---------------------------------------
# lang = "ja"
# autoStartDashboard = true

View File

@@ -0,0 +1,96 @@
# Design Document
## Overview
[High-level description of the feature and its place in the overall system]
## Steering Document Alignment
### Technical Standards (tech.md)
[How the design follows documented technical patterns and standards]
### Project Structure (structure.md)
[How the implementation will follow project organization conventions]
## Code Reuse Analysis
[What existing code will be leveraged, extended, or integrated with this feature]
### Existing Components to Leverage
- **[Component/Utility Name]**: [How it will be used]
- **[Service/Helper Name]**: [How it will be extended]
### Integration Points
- **[Existing System/API]**: [How the new feature will integrate]
- **[Database/Storage]**: [How data will connect to existing schemas]
## Architecture
[Describe the overall architecture and design patterns used]
### Modular Design Principles
- **Single File Responsibility**: Each file should handle one specific concern or domain
- **Component Isolation**: Create small, focused components rather than large monolithic files
- **Service Layer Separation**: Separate data access, business logic, and presentation layers
- **Utility Modularity**: Break utilities into focused, single-purpose modules
```mermaid
graph TD
A[Component A] --> B[Component B]
B --> C[Component C]
```
## Components and Interfaces
### Component 1
- **Purpose:** [What this component does]
- **Interfaces:** [Public methods/APIs]
- **Dependencies:** [What it depends on]
- **Reuses:** [Existing components/utilities it builds upon]
### Component 2
- **Purpose:** [What this component does]
- **Interfaces:** [Public methods/APIs]
- **Dependencies:** [What it depends on]
- **Reuses:** [Existing components/utilities it builds upon]
## Data Models
### Model 1
```
[Define the structure of Model1 in your language]
- id: [unique identifier type]
- name: [string/text type]
- [Additional properties as needed]
```
### Model 2
```
[Define the structure of Model2 in your language]
- id: [unique identifier type]
- [Additional properties as needed]
```
## Error Handling
### Error Scenarios
1. **Scenario 1:** [Description]
- **Handling:** [How to handle]
- **User Impact:** [What user sees]
2. **Scenario 2:** [Description]
- **Handling:** [How to handle]
- **User Impact:** [What user sees]
## Testing Strategy
### Unit Testing
- [Unit testing approach]
- [Key components to test]
### Integration Testing
- [Integration testing approach]
- [Key flows to test]
### End-to-End Testing
- [E2E testing approach]
- [User scenarios to test]

View File

@@ -0,0 +1,51 @@
# Product Overview
## Product Purpose
[Describe the core purpose of this product/project. What problem does it solve?]
## Target Users
[Who are the primary users of this product? What are their needs and pain points?]
## Key Features
[List the main features that deliver value to users]
1. **Feature 1**: [Description]
2. **Feature 2**: [Description]
3. **Feature 3**: [Description]
## Business Objectives
[What are the business goals this product aims to achieve?]
- [Objective 1]
- [Objective 2]
- [Objective 3]
## Success Metrics
[How will we measure the success of this product?]
- [Metric 1]: [Target]
- [Metric 2]: [Target]
- [Metric 3]: [Target]
## Product Principles
[Core principles that guide product decisions]
1. **[Principle 1]**: [Explanation]
2. **[Principle 2]**: [Explanation]
3. **[Principle 3]**: [Explanation]
## Monitoring & Visibility (if applicable)
[How do users track progress and monitor the system?]
- **Dashboard Type**: [e.g., Web-based, CLI, Desktop app]
- **Real-time Updates**: [e.g., WebSocket, polling, push notifications]
- **Key Metrics Displayed**: [What information is most important to surface]
- **Sharing Capabilities**: [e.g., read-only links, exports, reports]
## Future Vision
[Where do we see this product evolving in the future?]
### Potential Enhancements
- **Remote Access**: [e.g., Tunnel features for sharing dashboards with stakeholders]
- **Analytics**: [e.g., Historical trends, performance metrics]
- **Collaboration**: [e.g., Multi-user support, commenting]

View File

@@ -0,0 +1,50 @@
# Requirements Document
## Introduction
[Provide a brief overview of the feature, its purpose, and its value to users]
## Alignment with Product Vision
[Explain how this feature supports the goals outlined in product.md]
## Requirements
### Requirement 1
**User Story:** As a [role], I want [feature], so that [benefit]
#### Acceptance Criteria
1. WHEN [event] THEN [system] SHALL [response]
2. IF [precondition] THEN [system] SHALL [response]
3. WHEN [event] AND [condition] THEN [system] SHALL [response]
### Requirement 2
**User Story:** As a [role], I want [feature], so that [benefit]
#### Acceptance Criteria
1. WHEN [event] THEN [system] SHALL [response]
2. IF [precondition] THEN [system] SHALL [response]
## Non-Functional Requirements
### Code Architecture and Modularity
- **Single Responsibility Principle**: Each file should have a single, well-defined purpose
- **Modular Design**: Components, utilities, and services should be isolated and reusable
- **Dependency Management**: Minimize interdependencies between modules
- **Clear Interfaces**: Define clean contracts between components and layers
### Performance
- [Performance requirements]
### Security
- [Security requirements]
### Reliability
- [Reliability requirements]
### Usability
- [Usability requirements]

View File

@@ -0,0 +1,145 @@
# Project Structure
## Directory Organization
```
[Define your project's directory structure. Examples below - adapt to your project type]
Example for a library/package:
project-root/
├── src/ # Source code
├── tests/ # Test files
├── docs/ # Documentation
├── examples/ # Usage examples
└── [build/dist/out] # Build output
Example for an application:
project-root/
├── [src/app/lib] # Main source code
├── [assets/resources] # Static resources
├── [config/settings] # Configuration
├── [scripts/tools] # Build/utility scripts
└── [tests/spec] # Test files
Common patterns:
- Group by feature/module
- Group by layer (UI, business logic, data)
- Group by type (models, controllers, views)
- Flat structure for simple projects
```
## Naming Conventions
### Files
- **Components/Modules**: [e.g., `PascalCase`, `snake_case`, `kebab-case`]
- **Services/Handlers**: [e.g., `UserService`, `user_service`, `user-service`]
- **Utilities/Helpers**: [e.g., `dateUtils`, `date_utils`, `date-utils`]
- **Tests**: [e.g., `[filename]_test`, `[filename].test`, `[filename]Test`]
### Code
- **Classes/Types**: [e.g., `PascalCase`, `CamelCase`, `snake_case`]
- **Functions/Methods**: [e.g., `camelCase`, `snake_case`, `PascalCase`]
- **Constants**: [e.g., `UPPER_SNAKE_CASE`, `SCREAMING_CASE`, `PascalCase`]
- **Variables**: [e.g., `camelCase`, `snake_case`, `lowercase`]
## Import Patterns
### Import Order
1. External dependencies
2. Internal modules
3. Relative imports
4. Style imports
### Module/Package Organization
```
[Describe your project's import/include patterns]
Examples:
- Absolute imports from project root
- Relative imports within modules
- Package/namespace organization
- Dependency management approach
```
## Code Structure Patterns
[Define common patterns for organizing code within files. Below are examples - choose what applies to your project]
### Module/Class Organization
```
Example patterns:
1. Imports/includes/dependencies
2. Constants and configuration
3. Type/interface definitions
4. Main implementation
5. Helper/utility functions
6. Exports/public API
```
### Function/Method Organization
```
Example patterns:
- Input validation first
- Core logic in the middle
- Error handling throughout
- Clear return points
```
### File Organization Principles
```
Choose what works for your project:
- One class/module per file
- Related functionality grouped together
- Public API at the top/bottom
- Implementation details hidden
```
## Code Organization Principles
1. **Single Responsibility**: Each file should have one clear purpose
2. **Modularity**: Code should be organized into reusable modules
3. **Testability**: Structure code to be easily testable
4. **Consistency**: Follow patterns established in the codebase
## Module Boundaries
[Define how different parts of your project interact and maintain separation of concerns]
Examples of boundary patterns:
- **Core vs Plugins**: Core functionality vs extensible plugins
- **Public API vs Internal**: What's exposed vs implementation details
- **Platform-specific vs Cross-platform**: OS-specific code isolation
- **Stable vs Experimental**: Production code vs experimental features
- **Dependencies direction**: Which modules can depend on which
## Code Size Guidelines
[Define your project's guidelines for file and function sizes]
Suggested guidelines:
- **File size**: [Define maximum lines per file]
- **Function/Method size**: [Define maximum lines per function]
- **Class/Module complexity**: [Define complexity limits]
- **Nesting depth**: [Maximum nesting levels]
## Dashboard/Monitoring Structure (if applicable)
[How dashboard or monitoring components are organized]
### Example Structure:
```
src/
└── dashboard/ # Self-contained dashboard subsystem
├── server/ # Backend server components
├── client/ # Frontend assets
├── shared/ # Shared types/utilities
└── public/ # Static assets
```
### Separation of Concerns
- Dashboard isolated from core business logic
- Own CLI entry point for independent operation
- Minimal dependencies on main application
- Can be disabled without affecting core functionality
## Documentation Standards
- All public APIs must have documentation
- Complex logic should include inline comments
- README files for major modules
- Follow language-specific documentation conventions

View File

@@ -0,0 +1,139 @@
# Tasks Document
- [ ] 1. Create core interfaces in src/types/feature.ts
- File: src/types/feature.ts
- Define TypeScript interfaces for feature data structures
- Extend existing base interfaces from base.ts
- Purpose: Establish type safety for feature implementation
- _Leverage: src/types/base.ts_
- _Requirements: 1.1_
- _Prompt: Role: TypeScript Developer specializing in type systems and interfaces | Task: Create comprehensive TypeScript interfaces for the feature data structures following requirements 1.1, extending existing base interfaces from src/types/base.ts | Restrictions: Do not modify existing base interfaces, maintain backward compatibility, follow project naming conventions | Success: All interfaces compile without errors, proper inheritance from base types, full type coverage for feature requirements_
- [ ] 2. Create base model class in src/models/FeatureModel.ts
- File: src/models/FeatureModel.ts
- Implement base model extending BaseModel class
- Add validation methods using existing validation utilities
- Purpose: Provide data layer foundation for feature
- _Leverage: src/models/BaseModel.ts, src/utils/validation.ts_
- _Requirements: 2.1_
- _Prompt: Role: Backend Developer with expertise in Node.js and data modeling | Task: Create a base model class extending BaseModel and implementing validation following requirement 2.1, leveraging existing patterns from src/models/BaseModel.ts and src/utils/validation.ts | Restrictions: Must follow existing model patterns, do not bypass validation utilities, maintain consistent error handling | Success: Model extends BaseModel correctly, validation methods implemented and tested, follows project architecture patterns_
- [ ] 3. Add specific model methods to FeatureModel.ts
- File: src/models/FeatureModel.ts (continue from task 2)
- Implement create, update, delete methods
- Add relationship handling for foreign keys
- Purpose: Complete model functionality for CRUD operations
- _Leverage: src/models/BaseModel.ts_
- _Requirements: 2.2, 2.3_
- _Prompt: Role: Backend Developer with expertise in ORM and database operations | Task: Implement CRUD methods and relationship handling in FeatureModel.ts following requirements 2.2 and 2.3, extending patterns from src/models/BaseModel.ts | Restrictions: Must maintain transaction integrity, follow existing relationship patterns, do not duplicate base model functionality | Success: All CRUD operations work correctly, relationships are properly handled, database operations are atomic and efficient_
- [ ] 4. Create model unit tests in tests/models/FeatureModel.test.ts
- File: tests/models/FeatureModel.test.ts
- Write tests for model validation and CRUD methods
- Use existing test utilities and fixtures
- Purpose: Ensure model reliability and catch regressions
- _Leverage: tests/helpers/testUtils.ts, tests/fixtures/data.ts_
- _Requirements: 2.1, 2.2_
- _Prompt: Role: QA Engineer with expertise in unit testing and Jest/Mocha frameworks | Task: Create comprehensive unit tests for FeatureModel validation and CRUD methods covering requirements 2.1 and 2.2, using existing test utilities from tests/helpers/testUtils.ts and fixtures from tests/fixtures/data.ts | Restrictions: Must test both success and failure scenarios, do not test external dependencies directly, maintain test isolation | Success: All model methods are tested with good coverage, edge cases covered, tests run independently and consistently_
- [ ] 5. Create service interface in src/services/IFeatureService.ts
- File: src/services/IFeatureService.ts
- Define service contract with method signatures
- Extend base service interface patterns
- Purpose: Establish service layer contract for dependency injection
- _Leverage: src/services/IBaseService.ts_
- _Requirements: 3.1_
- _Prompt: Role: Software Architect specializing in service-oriented architecture and TypeScript interfaces | Task: Design service interface contract following requirement 3.1, extending base service patterns from src/services/IBaseService.ts for dependency injection | Restrictions: Must maintain interface segregation principle, do not expose internal implementation details, ensure contract compatibility with DI container | Success: Interface is well-defined with clear method signatures, extends base service appropriately, supports all required service operations_
- [ ] 6. Implement feature service in src/services/FeatureService.ts
- File: src/services/FeatureService.ts
- Create concrete service implementation using FeatureModel
- Add error handling with existing error utilities
- Purpose: Provide business logic layer for feature operations
- _Leverage: src/services/BaseService.ts, src/utils/errorHandler.ts, src/models/FeatureModel.ts_
- _Requirements: 3.2_
- _Prompt: Role: Backend Developer with expertise in service layer architecture and business logic | Task: Implement concrete FeatureService following requirement 3.2, using FeatureModel and extending BaseService patterns with proper error handling from src/utils/errorHandler.ts | Restrictions: Must implement interface contract exactly, do not bypass model validation, maintain separation of concerns from data layer | Success: Service implements all interface methods correctly, robust error handling implemented, business logic is well-encapsulated and testable_
- [ ] 7. Add service dependency injection in src/utils/di.ts
- File: src/utils/di.ts (modify existing)
- Register FeatureService in dependency injection container
- Configure service lifetime and dependencies
- Purpose: Enable service injection throughout application
- _Leverage: existing DI configuration in src/utils/di.ts_
- _Requirements: 3.1_
- _Prompt: Role: DevOps Engineer with expertise in dependency injection and IoC containers | Task: Register FeatureService in DI container following requirement 3.1, configuring appropriate lifetime and dependencies using existing patterns from src/utils/di.ts | Restrictions: Must follow existing DI container patterns, do not create circular dependencies, maintain service resolution efficiency | Success: FeatureService is properly registered and resolvable, dependencies are correctly configured, service lifetime is appropriate for use case_
- [ ] 8. Create service unit tests in tests/services/FeatureService.test.ts
- File: tests/services/FeatureService.test.ts
- Write tests for service methods with mocked dependencies
- Test error handling scenarios
- Purpose: Ensure service reliability and proper error handling
- _Leverage: tests/helpers/testUtils.ts, tests/mocks/modelMocks.ts_
- _Requirements: 3.2, 3.3_
- _Prompt: Role: QA Engineer with expertise in service testing and mocking frameworks | Task: Create comprehensive unit tests for FeatureService methods covering requirements 3.2 and 3.3, using mocked dependencies from tests/mocks/modelMocks.ts and test utilities | Restrictions: Must mock all external dependencies, test business logic in isolation, do not test framework code | Success: All service methods tested with proper mocking, error scenarios covered, tests verify business logic correctness and error handling_
- [ ] 4. Create API endpoints
- Design API structure
- _Leverage: src/api/baseApi.ts, src/utils/apiUtils.ts_
- _Requirements: 4.0_
- _Prompt: Role: API Architect specializing in RESTful design and Express.js | Task: Design comprehensive API structure following requirement 4.0, leveraging existing patterns from src/api/baseApi.ts and utilities from src/utils/apiUtils.ts | Restrictions: Must follow REST conventions, maintain API versioning compatibility, do not expose internal data structures directly | Success: API structure is well-designed and documented, follows existing patterns, supports all required operations with proper HTTP methods and status codes_
- [ ] 4.1 Set up routing and middleware
- Configure application routes
- Add authentication middleware
- Set up error handling middleware
- _Leverage: src/middleware/auth.ts, src/middleware/errorHandler.ts_
- _Requirements: 4.1_
- _Prompt: Role: Backend Developer with expertise in Express.js middleware and routing | Task: Configure application routes and middleware following requirement 4.1, integrating authentication from src/middleware/auth.ts and error handling from src/middleware/errorHandler.ts | Restrictions: Must maintain middleware order, do not bypass security middleware, ensure proper error propagation | Success: Routes are properly configured with correct middleware chain, authentication works correctly, errors are handled gracefully throughout the request lifecycle_
- [ ] 4.2 Implement CRUD endpoints
- Create API endpoints
- Add request validation
- Write API integration tests
- _Leverage: src/controllers/BaseController.ts, src/utils/validation.ts_
- _Requirements: 4.2, 4.3_
- _Prompt: Role: Full-stack Developer with expertise in API development and validation | Task: Implement CRUD endpoints following requirements 4.2 and 4.3, extending BaseController patterns and using validation utilities from src/utils/validation.ts | Restrictions: Must validate all inputs, follow existing controller patterns, ensure proper HTTP status codes and responses | Success: All CRUD operations work correctly, request validation prevents invalid data, integration tests pass and cover all endpoints_
- [ ] 5. Add frontend components
- Plan component architecture
- _Leverage: src/components/BaseComponent.tsx, src/styles/theme.ts_
- _Requirements: 5.0_
- _Prompt: Role: Frontend Architect with expertise in React component design and architecture | Task: Plan comprehensive component architecture following requirement 5.0, leveraging base patterns from src/components/BaseComponent.tsx and theme system from src/styles/theme.ts | Restrictions: Must follow existing component patterns, maintain design system consistency, ensure component reusability | Success: Architecture is well-planned and documented, components are properly organized, follows existing patterns and theme system_
- [ ] 5.1 Create base UI components
- Set up component structure
- Implement reusable components
- Add styling and theming
- _Leverage: src/components/BaseComponent.tsx, src/styles/theme.ts_
- _Requirements: 5.1_
- _Prompt: Role: Frontend Developer specializing in React and component architecture | Task: Create reusable UI components following requirement 5.1, extending BaseComponent patterns and using existing theme system from src/styles/theme.ts | Restrictions: Must use existing theme variables, follow component composition patterns, ensure accessibility compliance | Success: Components are reusable and properly themed, follow existing architecture, accessible and responsive_
- [ ] 5.2 Implement feature-specific components
- Create feature components
- Add state management
- Connect to API endpoints
- _Leverage: src/hooks/useApi.ts, src/components/BaseComponent.tsx_
- _Requirements: 5.2, 5.3_
- _Prompt: Role: React Developer with expertise in state management and API integration | Task: Implement feature-specific components following requirements 5.2 and 5.3, using API hooks from src/hooks/useApi.ts and extending BaseComponent patterns | Restrictions: Must use existing state management patterns, handle loading and error states properly, maintain component performance | Success: Components are fully functional with proper state management, API integration works smoothly, user experience is responsive and intuitive_
- [ ] 6. Integration and testing
- Plan integration approach
- _Leverage: src/utils/integrationUtils.ts, tests/helpers/testUtils.ts_
- _Requirements: 6.0_
- _Prompt: Role: Integration Engineer with expertise in system integration and testing strategies | Task: Plan comprehensive integration approach following requirement 6.0, leveraging integration utilities from src/utils/integrationUtils.ts and test helpers | Restrictions: Must consider all system components, ensure proper test coverage, maintain integration test reliability | Success: Integration plan is comprehensive and feasible, all system components work together correctly, integration points are well-tested_
- [ ] 6.1 Write end-to-end tests
- Set up E2E testing framework
- Write user journey tests
- Add test automation
- _Leverage: tests/helpers/testUtils.ts, tests/fixtures/data.ts_
- _Requirements: All_
- _Prompt: Role: QA Automation Engineer with expertise in E2E testing and test frameworks like Cypress or Playwright | Task: Implement comprehensive end-to-end tests covering all requirements, setting up testing framework and user journey tests using test utilities and fixtures | Restrictions: Must test real user workflows, ensure tests are maintainable and reliable, do not test implementation details | Success: E2E tests cover all critical user journeys, tests run reliably in CI/CD pipeline, user experience is validated from end-to-end_
- [ ] 6.2 Final integration and cleanup
- Integrate all components
- Fix any integration issues
- Clean up code and documentation
- _Leverage: src/utils/cleanup.ts, docs/templates/_
- _Requirements: All_
- _Prompt: Role: Senior Developer with expertise in code quality and system integration | Task: Complete final integration of all components and perform comprehensive cleanup covering all requirements, using cleanup utilities and documentation templates | Restrictions: Must not break existing functionality, ensure code quality standards are met, maintain documentation consistency | Success: All components are fully integrated and working together, code is clean and well-documented, system meets all requirements and quality standards_

View File

@@ -0,0 +1,99 @@
# Technology Stack
## Project Type
[Describe what kind of project this is: web application, CLI tool, desktop application, mobile app, library, API service, embedded system, game, etc.]
## Core Technologies
### Primary Language(s)
- **Language**: [e.g., Python 3.11, Go 1.21, TypeScript, Rust, C++]
- **Runtime/Compiler**: [if applicable]
- **Language-specific tools**: [package managers, build tools, etc.]
### Key Dependencies/Libraries
[List the main libraries and frameworks your project depends on]
- **[Library/Framework name]**: [Purpose and version]
- **[Library/Framework name]**: [Purpose and version]
### Application Architecture
[Describe how your application is structured - this could be MVC, event-driven, plugin-based, client-server, standalone, microservices, monolithic, etc.]
### Data Storage (if applicable)
- **Primary storage**: [e.g., PostgreSQL, files, in-memory, cloud storage]
- **Caching**: [e.g., Redis, in-memory, disk cache]
- **Data formats**: [e.g., JSON, Protocol Buffers, XML, binary]
### External Integrations (if applicable)
- **APIs**: [External services you integrate with]
- **Protocols**: [e.g., HTTP/REST, gRPC, WebSocket, TCP/IP]
- **Authentication**: [e.g., OAuth, API keys, certificates]
### Monitoring & Dashboard Technologies (if applicable)
- **Dashboard Framework**: [e.g., React, Vue, vanilla JS, terminal UI]
- **Real-time Communication**: [e.g., WebSocket, Server-Sent Events, polling]
- **Visualization Libraries**: [e.g., Chart.js, D3, terminal graphs]
- **State Management**: [e.g., Redux, Vuex, file system as source of truth]
## Development Environment
### Build & Development Tools
- **Build System**: [e.g., Make, CMake, Gradle, npm scripts, cargo]
- **Package Management**: [e.g., pip, npm, cargo, go mod, apt, brew]
- **Development workflow**: [e.g., hot reload, watch mode, REPL]
### Code Quality Tools
- **Static Analysis**: [Tools for code quality and correctness]
- **Formatting**: [Code style enforcement tools]
- **Testing Framework**: [Unit, integration, and/or end-to-end testing tools]
- **Documentation**: [Documentation generation tools]
### Version Control & Collaboration
- **VCS**: [e.g., Git, Mercurial, SVN]
- **Branching Strategy**: [e.g., Git Flow, GitHub Flow, trunk-based]
- **Code Review Process**: [How code reviews are conducted]
### Dashboard Development (if applicable)
- **Live Reload**: [e.g., Hot module replacement, file watchers]
- **Port Management**: [e.g., Dynamic allocation, configurable ports]
- **Multi-Instance Support**: [e.g., Running multiple dashboards simultaneously]
## Deployment & Distribution (if applicable)
- **Target Platform(s)**: [Where/how the project runs: cloud, on-premise, desktop, mobile, embedded]
- **Distribution Method**: [How users get your software: download, package manager, app store, SaaS]
- **Installation Requirements**: [Prerequisites, system requirements]
- **Update Mechanism**: [How updates are delivered]
## Technical Requirements & Constraints
### Performance Requirements
- [e.g., response time, throughput, memory usage, startup time]
- [Specific benchmarks or targets]
### Compatibility Requirements
- **Platform Support**: [Operating systems, architectures, versions]
- **Dependency Versions**: [Minimum/maximum versions of dependencies]
- **Standards Compliance**: [Industry standards, protocols, specifications]
### Security & Compliance
- **Security Requirements**: [Authentication, encryption, data protection]
- **Compliance Standards**: [GDPR, HIPAA, SOC2, etc. if applicable]
- **Threat Model**: [Key security considerations]
### Scalability & Reliability
- **Expected Load**: [Users, requests, data volume]
- **Availability Requirements**: [Uptime targets, disaster recovery]
- **Growth Projections**: [How the system needs to scale]
## Technical Decisions & Rationale
[Document key architectural and technology choices]
### Decision Log
1. **[Technology/Pattern Choice]**: [Why this was chosen, alternatives considered]
2. **[Architecture Decision]**: [Rationale, trade-offs accepted]
3. **[Tool/Library Selection]**: [Reasoning, evaluation criteria]
## Known Limitations
[Document any technical debt, limitations, or areas for improvement]
- [Limitation 1]: [Impact and potential future solutions]
- [Limitation 2]: [Why it exists and when it might be addressed]

View File

@@ -0,0 +1,64 @@
# User Templates
This directory allows you to create custom templates that override the default Spec Workflow templates.
## How to Use Custom Templates
1. **Create your custom template file** in this directory with the exact same name as the default template you want to override:
- `requirements-template.md` - Override requirements document template
- `design-template.md` - Override design document template
- `tasks-template.md` - Override tasks document template
- `product-template.md` - Override product steering template
- `tech-template.md` - Override tech steering template
- `structure-template.md` - Override structure steering template
2. **Template Loading Priority**:
- The system first checks this `user-templates/` directory
- If a matching template is found here, it will be used
- Otherwise, the default template from `templates/` will be used
## Example Custom Template
To create a custom requirements template:
1. Create a file named `requirements-template.md` in this directory
2. Add your custom structure, for example:
```markdown
# Requirements Document
## Executive Summary
[Your custom section]
## Business Requirements
[Your custom structure]
## Technical Requirements
[Your custom fields]
## Custom Sections
[Add any sections specific to your workflow]
```
## Template Variables
Templates can include placeholders that will be replaced when documents are created:
- `{{projectName}}` - The name of your project
- `{{featureName}}` - The name of the feature being specified
- `{{date}}` - The current date
- `{{author}}` - The document author
## Best Practices
1. **Start from defaults**: Copy a default template from `../templates/` as a starting point
2. **Keep structure consistent**: Maintain similar section headers for tool compatibility
3. **Document changes**: Add comments explaining why sections were added/modified
4. **Version control**: Track your custom templates in version control
5. **Test thoroughly**: Ensure custom templates work with the spec workflow tools
## Notes
- Custom templates are project-specific and not included in the package distribution
- The `templates/` directory contains the default templates which are updated with each version
- Your custom templates in this directory are preserved during updates
- If a custom template has errors, the system will fall back to the default template

View File

@@ -1,3 +1,35 @@
# Frontend (Astro) # Frontend (Astro)
This package hosts the Astro application for enchun.tw. Use `pnpm dev` to run the site locally once dependencies are installed at the workspace root. This package hosts the Astro application for enchun.tw. This is a simple SSG website using Cloudflare Pages.
## Development
Choose the appropriate development command based on your needs:
```bash
# Standard Astro development (uses .env.local)
pnpm dev
# Cloudflare Pages development (uses dev.vars, simulates production environment)
pnpm dev:pages
```
## Environment Configuration
The application uses Cloudflare Pages with Wrangler for deployment and environment management.
### Local Development
- **Astro dev** (`pnpm dev`): Uses `.env.local` file (variables must be prefixed with `PUBLIC_` for client-side access)
- **Pages dev** (`pnpm dev:pages`): Uses `dev.vars` file, simulates Cloudflare Pages environment
- API URL: `https://enchun-admin.anlstudio.cc`
### Production
- Uses `wrangler.toml` configuration
- API URL: `https://enchun-admin.anlstudio.cc`
## Environment Variables
- `PUBLIC_PAYLOAD_CMS_URL`: Base URL for the Payload CMS API (client-side accessible)
- `PAYLOAD_CMS_API_KEY`: API key for Payload CMS authentication (set via Cloudflare dashboard)
**Note**: Environment variables that need to be accessed in browser/client-side code must be prefixed with `PUBLIC_` in Astro.

View File

@@ -1,12 +1,25 @@
import { defineConfig } from 'astro/config'; // @ts-check
import cloudflare from '@astrojs/cloudflare'; import { defineConfig } from "astro/config";
import tailwind from '@astrojs/tailwind'; import cloudflare from "@astrojs/cloudflare";
import tailwindcss from "@tailwindcss/vite";
// https://astro.build/config
export default defineConfig({ export default defineConfig({
output: 'server', output: "server",
adapter: cloudflare(), adapter: cloudflare(),
integrations: [tailwind()], vite: {
plugins: [tailwindcss()],
server: {
proxy: {
'/api': {
target: 'https://enchun-admin.anlstudio.cc',
changeOrigin: true,
secure: true,
},
},
},
},
typescript: { typescript: {
strict: true strict: true,
} },
}); });

3
apps/frontend/dev.vars Normal file
View File

@@ -0,0 +1,3 @@
# Local development environment variables
# This file is used by wrangler for local development
PAYLOAD_CMS_URL=https://enchun-admin.anlstudio.cc

View File

@@ -4,20 +4,23 @@
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "astro dev", "dev": "astro dev --host --port 4321",
"dev:pages": "wrangler pages dev --compatibility-date=2024-01-01",
"build": "astro build", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"check": "astro check" "check": "astro check",
"deploy": "wrangler pages deploy dist"
}, },
"dependencies": { "dependencies": {
"@astrojs/cloudflare": "^9.0.0", "@astrojs/cloudflare": "^12.6.9",
"@astrojs/tailwind": "^5.0.0", "@tailwindcss/vite": "^4.1.14",
"astro": "^4.0.0", "astro": "^5.14.1",
"better-auth": "^1.3.13" "better-auth": "^1.3.13"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/typography": "^0.5.19",
"autoprefixer": "^10.4.0", "autoprefixer": "^10.4.0",
"tailwindcss": "^3.4.0", "tailwindcss": "^4.1.14",
"typescript": "^5.4.0" "typescript": "^5.4.0"
} }
} }

4751
apps/frontend/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +0,0 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
};

View File

@@ -0,0 +1,14 @@
<svg width="182" height="237" viewBox="0 0 182 237" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M149.22 74.7164C148.84 56.9861 143.014 41.5353 130.223 28.9974C120.851 19.7523 109.58 14.3065 96.4089 13.2933C75.3857 11.647 58.6685 20.0056 46.2572 36.8494C36.5055 50.1472 32.9595 65.3447 34.8591 81.8086C36.5055 96.3728 42.4579 109.037 52.8428 119.422C65.5074 132.087 81.0848 137.659 98.9418 135.886C110.467 134.746 120.725 130.314 129.97 123.348C130.603 122.842 131.236 122.209 132.123 121.955C133.516 121.575 134.909 122.082 135.669 123.348C136.429 124.615 136.302 125.881 135.289 127.021C132.376 130.314 128.957 133.227 125.284 135.633C114.266 143.232 101.981 146.904 88.5569 146.524C71.2064 146.018 56.2622 139.686 43.7243 127.654C31.8196 116.13 24.7275 102.199 22.0679 85.8613C17.3821 56.2262 30.2999 25.3247 57.0221 9.49398C83.6177 -6.33671 117.052 -2.03076 138.835 19.8789C150.993 32.0369 158.085 46.6011 160.238 63.5716C162.011 77.6293 160.112 91.307 154.286 104.225C152.513 108.278 149.6 109.164 145.801 107.138C129.21 98.0192 112.62 88.9007 96.1556 79.7823C95.1424 79.2757 94.3826 79.0224 93.2427 79.529C90.2033 80.6688 86.9105 79.0224 85.7707 75.9829C84.6308 72.8168 86.4039 69.524 89.4434 68.3842C92.6095 67.371 96.0289 69.0174 96.9155 72.1835C97.1688 73.3233 97.802 73.8299 98.6885 74.2099C114.013 81.0487 129.21 87.7609 144.534 94.7265C145.674 95.233 146.054 94.9797 146.307 93.8399C148.334 87.5076 149.347 81.1754 149.22 74.7164Z" fill="#3083BF"/>
<path d="M135.922 68.5108C135.922 69.6506 135.922 70.5372 135.922 71.4237C135.922 72.9434 134.909 73.9566 133.643 74.0832C131.996 74.3365 130.857 73.5766 130.477 72.0569C130.097 70.2839 129.843 68.5108 129.337 66.7378C125.537 53.3134 117.812 43.0551 104.388 38.2425C90.8365 33.43 78.172 35.7096 67.0272 44.9548C62.088 49.0074 58.4153 53.9466 55.5024 59.519C54.7425 61.0387 53.4761 61.672 52.2096 61.4187C50.8165 61.1654 50.0567 60.2789 49.6767 59.0124C49.5501 58.5058 49.6767 58.1259 49.8034 57.6193C51.1965 51.287 54.1093 45.7146 58.2886 40.6488C65.0008 32.5435 73.6127 27.4777 83.9977 25.578C96.5356 23.2984 107.934 26.2112 117.939 33.8099C128.324 41.5353 134.149 52.0469 135.922 64.8381C135.796 65.9779 135.922 67.371 135.922 68.5108Z" fill="#939494"/>
<path d="M91.5964 164.128C72.8529 163.875 56.1356 158.303 42.078 145.511C40.6849 144.245 40.4316 143.105 41.0648 141.839C41.698 140.699 42.7112 140.066 43.9777 140.192C44.7375 140.319 45.2441 140.699 45.8774 141.079C53.3494 145.891 61.4548 149.437 70.0667 151.717C80.4516 154.503 91.0898 155.136 101.855 153.743C114.266 152.097 125.664 147.918 136.049 141.079C136.556 140.699 137.189 140.319 137.822 140.192C139.215 139.939 140.482 140.572 141.115 141.712C141.748 142.978 141.495 144.245 140.355 145.385C138.075 147.664 135.542 149.691 133.009 151.59C123.384 158.303 112.746 162.102 101.095 163.622C97.9287 163.875 94.7625 164.002 91.5964 164.128Z" fill="#3083BF"/>
<path d="M94.2561 91.9402C95.1426 91.9402 96.0291 91.8136 96.789 91.8136C98.4354 91.8136 99.3219 92.4468 99.5752 93.7132C99.8285 94.9797 99.0686 95.9929 97.6755 96.4994C94.3827 97.7659 90.9633 98.0192 87.5439 97.7659C77.7922 97.006 69.3069 90.2938 66.2674 81.0487C61.8348 67.4976 70.0668 52.9334 84.3777 49.5139C97.1689 46.3478 109.96 53.44 113.506 65.5979C113.633 66.1045 113.76 66.6111 113.886 67.1177C114.139 68.5108 113.506 69.7772 112.366 70.1572C111.227 70.5371 109.96 70.0305 109.327 68.6374C108.44 66.8644 107.301 65.218 106.034 63.6982C98.3088 54.5798 83.4912 55.3396 76.779 65.3446C72.0931 72.3101 73.6129 81.8086 80.1984 87.1277C84.3777 90.5471 88.937 92.0669 94.2561 91.9402Z" fill="#939494"/>
<path d="M88.81 122.335C70.8263 122.715 54.2358 108.531 49.0433 90.6738C47.9035 86.7478 47.2703 82.6952 47.2703 78.6425C47.2703 76.6162 48.0301 75.4764 49.5499 75.3497C51.1963 75.2231 52.0828 76.1096 52.4627 78.1359C54.1091 85.8613 57.2753 92.8268 62.4677 98.7792C68.8 106.125 76.9053 110.557 86.4037 112.33C95.0156 113.977 103.121 112.33 110.973 108.784C111.86 108.404 112.619 108.024 113.506 107.644C115.026 107.011 116.292 107.264 117.052 108.278C117.938 109.544 117.812 110.81 116.545 112.077C114.519 114.103 112.113 115.75 109.707 117.143C103.754 120.815 97.1686 122.335 88.81 122.335Z" fill="#939494"/>
<path d="M91.3431 180.339C79.0585 180.212 67.4071 177.173 56.6422 171.094C56.3889 170.967 56.1356 170.84 55.8823 170.714C54.6159 169.827 54.2359 168.687 54.8692 167.548C55.3757 166.408 56.5156 165.775 58.0353 166.281C62.5945 167.548 67.0271 168.814 71.5864 169.827C87.6704 173.373 103.501 172.487 119.205 167.674C120.725 167.168 122.371 166.661 123.891 166.281C125.411 165.775 126.677 166.281 127.31 167.548C127.944 168.814 127.437 170.207 126.044 171.094C117.052 176.413 107.427 179.452 97.0421 180.212C95.0158 180.212 93.1161 180.465 91.3431 180.339Z" fill="#3083BF"/>
<path d="M0.533691 217.007C0.882309 216.21 0.882309 215.325 1.14377 214.528C4.10703 203.636 16.8316 198.588 25.8085 204.964C31.5607 209.038 33.5652 214.705 32.7809 221.701C32.6937 222.143 32.5194 222.321 32.0836 222.321C27.1158 222.321 22.148 222.321 17.2674 222.321C16.8316 222.321 16.6573 222.143 16.6573 221.701C16.6573 220.107 16.6573 218.513 16.6573 216.919C16.6573 216.21 17.0059 216.299 17.4417 216.299C20.1435 216.299 22.8452 216.299 25.547 216.299C26.3314 216.299 26.5057 216.122 26.2443 215.413C24.2397 209.48 18.0517 206.912 13.0839 209.48C8.98768 211.606 6.72166 214.971 6.89597 219.753C7.07028 224.446 9.24914 227.811 13.5197 229.582C17.3545 231.176 21.015 230.556 24.1526 227.634C24.5883 227.191 24.8498 227.191 25.2856 227.634C26.5057 228.696 27.813 229.671 29.1204 230.645C29.469 230.91 29.5561 231.176 29.2075 231.53C25.4599 235.249 21.015 237.02 15.8729 236.489C7.94182 235.604 2.45109 230.379 0.795155 222.409C0.795155 222.232 0.795155 221.966 0.533691 221.878C0.533691 220.107 0.533691 218.601 0.533691 217.007Z" fill="#3083BF"/>
<path d="M102.592 213.111C103.289 212.403 103.899 211.783 104.509 211.251C109.041 207.266 116.1 208.418 118.802 213.642C119.674 215.325 119.935 217.184 120.022 219.044C120.022 224.269 120.022 229.582 120.022 234.807C120.022 235.515 119.935 235.781 119.151 235.781C117.408 235.692 115.752 235.692 114.009 235.781C113.311 235.781 113.137 235.515 113.137 234.895C113.137 230.025 113.137 225.154 113.137 220.284C113.137 219.575 113.05 218.956 112.963 218.247C112.266 214.794 108.867 213.377 105.816 215.236C104.683 215.945 103.725 217.007 102.853 218.07C102.592 218.424 102.592 218.867 102.592 219.221C102.592 224.446 102.592 229.582 102.592 234.807C102.592 235.604 102.417 235.869 101.633 235.781C99.8897 235.692 98.2338 235.781 96.4907 235.781C95.9678 235.781 95.7063 235.692 95.7063 235.072C95.7063 222.409 95.7063 209.746 95.7063 197.083C95.7063 196.551 95.8806 196.374 96.4035 196.374C98.1466 196.374 99.9769 196.463 101.72 196.374C102.417 196.374 102.592 196.551 102.592 197.26C102.592 202.13 102.592 207.001 102.592 211.871C102.592 212.137 102.592 212.491 102.592 213.111Z" fill="#3083BF"/>
<path d="M164.123 213.022C165.691 211.34 167.26 210.012 169.177 209.392C175.365 207.355 181.205 211.34 181.379 217.981C181.553 223.649 181.379 229.405 181.466 235.072C181.466 235.604 181.292 235.781 180.769 235.781C179.026 235.781 177.37 235.692 175.627 235.781C174.843 235.781 174.581 235.604 174.581 234.718C174.581 229.759 174.581 224.8 174.581 219.841C174.581 219.044 174.581 218.336 174.32 217.539C173.535 214.705 171.008 213.377 168.393 214.439C166.563 215.148 165.43 216.565 164.297 218.07C164.035 218.424 164.123 218.778 164.123 219.133C164.123 224.357 164.123 229.493 164.123 234.718C164.123 235.515 163.948 235.781 163.164 235.781C161.421 235.692 159.765 235.781 158.022 235.781C157.412 235.781 157.237 235.692 157.237 234.984C157.237 226.66 157.237 218.336 157.237 210.1C157.237 209.48 157.412 209.392 157.935 209.392C159.765 209.392 161.595 209.392 163.338 209.392C163.861 209.392 164.123 209.569 164.035 210.1C164.123 210.986 164.123 211.871 164.123 213.022Z" fill="#3083BF"/>
<path d="M45.5925 213.022C47.4227 210.986 49.253 209.657 51.6061 209.126C57.3583 207.798 62.5004 211.606 62.8491 217.627C63.1977 223.472 62.9362 229.316 62.9362 235.249C62.9362 235.692 62.8491 235.869 62.3261 235.869C60.4087 235.869 58.5785 235.869 56.6611 235.869C55.8767 235.869 56.051 235.426 56.051 234.984C56.051 230.025 56.051 224.977 56.051 220.018C56.051 219.31 55.9639 218.513 55.7895 217.804C54.918 214.439 51.519 213.199 48.5557 215.236C47.4227 216.033 46.6383 217.007 45.7668 218.07C45.4182 218.424 45.5053 218.867 45.5053 219.31C45.5053 224.534 45.5053 229.67 45.5053 234.895C45.5053 235.781 45.2439 235.958 44.4595 235.958C42.8035 235.869 41.0604 235.958 39.4045 235.958C38.7944 235.958 38.533 235.869 38.533 235.161C38.533 226.925 38.533 218.601 38.533 210.366C38.533 209.834 38.6201 209.569 39.2302 209.569C41.0604 209.569 42.8907 209.569 44.8081 209.569C45.4182 209.569 45.5053 209.746 45.5053 210.366C45.5925 210.986 45.5925 211.871 45.5925 213.022Z" fill="#3083BF"/>
<path d="M143.554 232.327C143.031 232.858 142.596 233.213 142.247 233.567C139.894 235.604 137.192 236.666 133.967 236.223C129.871 235.604 126.733 232.327 126.385 228.076C126.123 225.066 126.298 221.966 126.298 218.955C126.298 216.122 126.298 213.288 126.298 210.454C126.298 209.746 126.385 209.48 127.169 209.48C128.825 209.569 130.568 209.569 132.224 209.48C132.921 209.48 133.183 209.657 133.183 210.366C133.183 215.236 133.183 220.107 133.183 225.066C133.183 225.774 133.183 226.482 133.357 227.191C133.793 230.025 136.059 231.619 138.848 230.999C140.94 230.556 142.421 229.228 143.467 227.368C143.729 226.925 143.641 226.571 143.641 226.128C143.641 220.904 143.641 215.768 143.641 210.543C143.641 209.746 143.816 209.48 144.6 209.569C146.256 209.657 147.825 209.657 149.481 209.569C150.352 209.569 150.614 209.746 150.614 210.631C150.527 216.919 150.614 223.117 150.614 229.405C150.614 231.264 150.614 233.124 150.614 235.072C150.614 235.781 150.439 236.046 149.742 235.958C147.999 235.869 146.256 235.869 144.513 235.958C143.816 235.958 143.641 235.692 143.729 235.072C143.641 234.098 143.554 233.39 143.554 232.327Z" fill="#3083BF"/>
<path d="M90.2156 213.554C90.2156 214.262 90.2156 215.059 90.2156 215.768C90.2156 216.476 90.0413 216.565 89.4312 216.21C87.5138 215.148 85.5093 214.439 83.3304 214.439C78.1883 214.439 74.8764 218.159 75.3993 223.56C75.9223 228.874 80.1928 231.707 85.5093 230.556C86.9909 230.29 88.4725 229.759 89.9541 229.139C90.4771 228.874 90.6514 229.051 90.6514 229.582C90.6514 230.999 90.6514 232.504 90.6514 233.921C90.6514 234.364 90.5642 234.629 90.1285 234.718C85.4221 236.401 80.6286 236.932 75.9223 234.984C71.0416 232.947 68.427 229.139 68.1655 223.737C67.904 219.841 68.6884 216.299 71.3031 213.288C74.4406 209.657 78.5369 208.506 83.1561 208.772C85.2478 208.86 87.3395 209.303 89.3441 210.1C89.9541 210.366 90.3028 210.632 90.2156 211.428C90.1285 212.225 90.2156 212.845 90.2156 213.554Z" fill="#3083BF"/>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,8 @@
<svg width="919" height="201" viewBox="0 0 919 201" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 103.146C1.77071 99.1619 1.77071 94.7353 3.09875 90.7512C18.1498 36.3028 82.7808 11.0706 128.377 42.9429C157.593 63.3057 167.775 91.6365 163.791 126.607C163.348 128.821 162.463 129.706 160.249 129.706C135.017 129.706 109.784 129.706 84.9942 129.706C82.7808 129.706 81.8955 128.821 81.8955 126.607C81.8955 118.639 81.8955 110.671 81.8955 102.703C81.8955 99.1619 83.6662 99.6046 85.8796 99.6046C99.6026 99.6046 113.326 99.6046 127.049 99.6046C131.033 99.6046 131.918 98.7193 130.59 95.1779C120.408 65.519 88.9783 52.6816 63.7457 65.519C42.9398 76.1431 31.4302 92.9645 32.3155 116.869C33.2009 140.33 44.2678 157.152 65.959 166.005C85.4369 173.973 104.029 170.874 119.966 156.266C122.179 154.053 123.507 154.053 125.721 156.266C131.918 161.578 138.558 166.448 145.198 171.317C146.969 172.645 147.412 173.973 145.641 175.744C126.606 194.336 104.029 203.189 77.9114 200.533C37.6276 196.107 9.73892 169.989 1.32803 130.149C1.32803 129.263 1.32803 127.935 0 127.493C0 118.639 0 111.114 0 103.146Z" fill="#3083BF"/>
<path d="M518.376 83.6647C521.917 80.1233 525.016 77.0246 528.115 74.3686C551.134 54.4484 586.991 60.2032 600.714 86.3207C605.141 94.7315 606.469 104.028 606.912 113.324C606.912 139.441 606.912 166.001 606.912 192.119C606.912 195.66 606.469 196.988 602.485 196.988C593.631 196.546 585.22 196.546 576.367 196.988C572.825 196.988 571.94 195.66 571.94 192.562C571.94 168.215 571.94 143.868 571.94 119.521C571.94 115.98 571.497 112.881 571.055 109.34C567.513 92.0754 550.249 84.9927 534.755 94.2888C529 97.8301 524.131 103.142 519.704 108.454C518.376 110.225 518.376 112.438 518.376 114.209C518.376 140.326 518.376 166.001 518.376 192.119C518.376 196.103 517.491 197.431 513.506 196.988C504.653 196.546 496.242 196.988 487.388 196.988C484.732 196.988 483.404 196.546 483.404 193.447C483.404 130.145 483.404 66.8432 483.404 3.54131C483.404 0.885287 484.29 0 486.946 0C495.799 0 505.096 0.44267 513.949 0C517.491 0 518.376 0.885341 518.376 4.4267C518.376 28.7736 518.376 53.1205 518.376 77.4673C518.376 78.7953 518.376 80.566 518.376 83.6647Z" fill="#3083BF"/>
<path d="M830.907 83.2191C838.875 74.8084 846.843 68.1684 856.582 65.0697C888.012 54.8883 917.672 74.8084 918.557 108.009C919.443 136.34 918.557 165.113 919 193.444C919 196.1 918.115 196.985 915.459 196.985C906.605 196.985 898.194 196.543 889.34 196.985C885.356 196.985 884.028 196.1 884.028 191.673C884.028 166.884 884.028 142.094 884.028 117.305C884.028 113.321 884.028 109.779 882.7 105.795C878.716 91.6299 865.879 84.9898 852.598 90.3019C843.302 93.8432 837.547 100.926 831.792 108.451C830.464 110.222 830.907 111.993 830.907 113.763C830.907 139.881 830.907 165.556 830.907 191.673C830.907 195.657 830.022 196.985 826.038 196.985C817.184 196.543 808.773 196.985 799.92 196.985C796.821 196.985 795.935 196.543 795.935 193.001C795.935 151.39 795.935 109.779 795.935 68.6111C795.935 65.5124 796.821 65.0697 799.477 65.0697C808.773 65.0697 818.069 65.0697 826.923 65.0697C829.579 65.0697 830.907 65.9551 830.464 68.6111C830.907 73.0378 830.907 77.4644 830.907 83.2191Z" fill="#3083BF"/>
<path d="M228.864 83.2222C238.161 73.0408 247.457 66.4008 259.409 63.7447C288.626 57.1047 314.744 76.1395 316.515 106.241C318.285 135.457 316.957 164.674 316.957 194.332C316.957 196.546 316.515 197.431 313.859 197.431C304.12 197.431 294.824 197.431 285.085 197.431C281.1 197.431 281.986 195.218 281.986 193.004C281.986 168.215 281.986 142.983 281.986 118.193C281.986 114.652 281.543 110.668 280.658 107.126C276.231 90.305 258.967 84.1076 243.915 94.289C238.161 98.273 234.177 103.142 229.75 108.454C227.979 110.225 228.422 112.438 228.422 114.652C228.422 140.769 228.422 166.444 228.422 192.562C228.422 196.989 227.094 197.874 223.11 197.874C214.699 197.431 205.845 197.874 197.434 197.874C194.335 197.874 193.007 197.431 193.007 193.89C193.007 152.721 193.007 111.11 193.007 69.9421C193.007 67.2861 193.45 65.9581 196.549 65.9581C205.845 65.9581 215.141 65.9581 224.88 65.9581C227.979 65.9581 228.422 66.8434 228.422 69.9421C228.864 73.0408 228.864 77.4675 228.864 83.2222Z" fill="#3083BF"/>
<path d="M726.435 179.724C723.779 182.38 721.565 184.15 719.794 185.921C707.842 196.102 694.119 201.415 677.74 199.201C656.934 196.102 640.998 179.724 639.227 158.475C637.899 143.425 638.784 127.931 638.784 112.88C638.784 98.715 638.784 84.5495 638.784 70.3841C638.784 66.8427 639.227 65.5146 643.211 65.5146C651.622 65.9573 660.475 65.9573 668.886 65.5146C672.428 65.5146 673.756 66.4 673.756 69.9414C673.756 94.2882 673.756 118.635 673.756 143.425C673.756 146.966 673.756 150.507 674.641 154.049C676.855 168.214 688.364 176.182 702.53 173.084C713.154 170.87 720.68 164.23 725.992 154.934C727.32 152.721 726.877 150.95 726.877 148.737C726.877 122.619 726.877 96.9443 726.877 70.8267C726.877 66.8427 727.763 65.5147 731.747 65.9573C740.158 66.4 748.126 66.4 756.537 65.9573C760.963 65.9573 762.292 66.8427 762.292 71.2694C761.849 102.699 762.292 133.686 762.292 165.116C762.292 174.412 762.292 183.708 762.292 193.446C762.292 196.988 761.406 198.316 757.865 197.873C749.011 197.43 740.158 197.43 731.304 197.873C727.763 197.873 726.877 196.545 727.32 193.446C726.877 188.577 726.435 185.036 726.435 179.724Z" fill="#3083BF"/>
<path d="M455.516 85.8773C455.516 89.4187 455.516 93.4027 455.516 96.9441C455.516 100.485 454.63 100.928 451.532 99.1574C441.793 93.8454 431.611 90.304 420.544 90.304C394.426 90.304 377.604 108.896 380.26 135.899C382.916 162.459 404.608 176.625 431.611 170.87C439.137 169.542 446.662 166.886 454.188 163.787C456.844 162.459 457.729 163.345 457.729 166.001C457.729 173.083 457.729 180.609 457.729 187.691C457.729 189.905 457.286 191.233 455.073 191.675C431.168 200.086 406.821 202.742 382.916 193.004C358.126 182.822 344.846 163.787 343.518 136.784C342.19 117.307 346.174 99.6001 359.454 84.5493C375.391 66.3998 396.197 60.6451 419.659 61.9731C430.283 62.4158 440.907 64.6291 451.089 68.6132C454.188 69.9412 455.958 71.2692 455.516 75.2532C455.073 79.2373 455.516 82.3359 455.516 85.8773Z" fill="#3083BF"/>
</svg>

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -0,0 +1,10 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_10_5456)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M44.8988 42.2096H56.4492L58.1785 28.4124H44.8988V19.6033C44.8988 15.6088 45.9771 12.8864 51.5452 12.8864L58.6467 12.883V0.543068C57.4179 0.375538 53.2027 0 48.2987 0C38.06 0 31.0503 6.42952 31.0503 18.2376V28.4127H19.47V42.21H31.05V77.6128L44.8988 77.6124V42.2096Z" fill="#23608C"/>
</g>
<defs>
<clipPath id="clip0_10_5456">
<rect width="40" height="80" fill="white" transform="translate(19.47)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 606 B

View File

@@ -0,0 +1,3 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 27H22.5C23.325 27 24 26.325 24 25.5C24 24.675 23.325 24 22.5 24H6C5.175 24 4.5 24.675 4.5 25.5C4.5 26.325 5.175 27 6 27ZM6 19.5H18C18.825 19.5 19.5 18.825 19.5 18C19.5 17.175 18.825 16.5 18 16.5H6C5.175 16.5 4.5 17.175 4.5 18C4.5 18.825 5.175 19.5 6 19.5ZM4.5 10.5C4.5 11.325 5.175 12 6 12H22.5C23.325 12 24 11.325 24 10.5C24 9.675 23.325 9 22.5 9H6C5.175 9 4.5 9.675 4.5 10.5ZM30.45 22.32L26.13 18L30.45 13.68C30.5889 13.5411 30.699 13.3763 30.7742 13.1948C30.8493 13.0134 30.888 12.8189 30.888 12.6225C30.888 12.4261 30.8493 12.2316 30.7742 12.0502C30.699 11.8687 30.5889 11.7039 30.45 11.565C30.3111 11.4261 30.1463 11.316 29.9648 11.2408C29.7834 11.1657 29.5889 11.127 29.3925 11.127C29.1961 11.127 29.0016 11.1657 28.8202 11.2408C28.6387 11.316 28.4739 11.4261 28.335 11.565L22.95 16.95C22.8109 17.0888 22.7006 17.2536 22.6254 17.4351C22.5501 17.6165 22.5113 17.811 22.5113 18.0075C22.5113 18.204 22.5501 18.3985 22.6254 18.5799C22.7006 18.7614 22.8109 18.9262 22.95 19.065L28.335 24.45C28.92 25.035 29.865 25.035 30.45 24.45C31.02 23.865 31.035 22.905 30.45 22.32V22.32Z" fill="#3083BF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,25 @@
// 301 Redirects for SEO preservation
// Map old URLs to new URLs
const redirects = {
// Old static pages
'/about-enchun': '/about-enchun',
'/contact-us': '/contact-us',
'/marketing-solutions': '/marketing-solutions',
'/news': '/news',
'/teams': '/teams',
'/website-portfolio': '/website-portfolio',
'/marketingclass': '/marketing-class', // deprecated, but redirect if needed
// Blog posts - keep same for SEO
'/xing-xiao-fang-da-jing/2-zhao-yao-kong-xiao-fei-zhe-de-xin': '/xing-xiao-fang-da-jing/2-zhao-yao-kong-xiao-fei-zhe-de-xin',
// Add all from sitemap...
'/wen-zhang-fen-lei/en-qun-shu-wei-zui-xin-gong-gao': '/wen-zhang-fen-lei/en-qun-shu-wei-zui-xin-gong-gao',
// Add all...
// Portfolios
'/webdesign-profolio/web-design-project-2': '/webdesign-profolio/web-design-project-2',
// Add all...
};
export default redirects;

View File

@@ -0,0 +1,90 @@
---
import { Image } from 'astro:assets';
// Footer component with client-side data fetching
---
<footer class="bg-[var(--color-tropical-blue)] py-10 mt-auto">
<div class="max-w-5xl mx-auto px-4">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-8 mb-8">
<div class="col-span-2">
<Image src="/enchun-logo.svg"
alt="Enchun Digital Logo" class="h-auto w-32 mb-4"
width={919}
height={201}
loading="eager"
decoding="async"
/>
<p class="text-[var(--color-st-tropaz)] text-sm font-light leading-relaxed">恩群數位累積多年廣告行銷操作經驗,擁有全方位行銷人才,讓我們可以為客戶精準的規劃每一分廣告預算,讓你的品牌深入人心。更重要的是恩群的存在,為了成為每家公司最佳數位夥伴,作為彼此最堅強的後盾,你會知道有我們的陪伴 你並不孤單。</p>
</div>
<div>
<h3 class="text-lg font-bold text-[var(--color-st-tropaz)] mb-4">聯絡我們</h3>
<a href="https://www.facebook.com/EnChun-Taiwan-100979265112420" target="_blank" class="flex items-center mb-2">
<Image src="/fb-icon.svg"
alt="Phone Icon" class="h-auto w-6 mb-2"
width={16}
height={16}
loading="eager"
decoding="async"
/>
</a>
<p class="text-[var(--color-st-tropaz)] mb-2">諮詢電話:<br> 02 5570 0527</p>
<a href="mailto:enchuntaiwan@gmail.com" class="text-primary hover:text-secondary transition-colors">enchuntaiwan@gmail.com</a>
</div>
<div>
<h3 class="text-lg font-bold text-[var(--color-st-tropaz)] mb-4">行銷方案</h3>
<ul class="space-y-2" id="marketing-solutions">
<li><span class="text-gray-500">載入中...</span></li>
</ul>
</div>
<div>
<h3 class="text-lg font-bold text-[var(--color-st-tropaz)] mb-4">行銷放大鏡</h3>
<ul class="space-y-2" id="marketing-articles">
<li><span class="text-gray-500">載入中...</span></li>
</ul>
</div>
</div>
<div class="absolute inset-x-0 w-screen bg-[var(--color-amber)] py-3 text-center">
<p class="text-[var(--color-tarawera)]">copyright ©  Enchun digital  2018 - {new Date().getFullYear()}</p>
</div>
</div>
</footer>
<script>
// Client-side data fetching for footer
async function loadFooterData() {
try {
console.log('Fetching footer data...');
const response = await fetch('/api/globals/footer?depth=2&draft=false&locale=undefined&trash=false');
const data = await response.json();
console.log('Footer data loaded:', data);
// Update marketing solutions
const marketingUl = document.getElementById('marketing-solutions');
if (marketingUl && data.navItems?.[0]?.childNavItems) {
const links = data.navItems[0].childNavItems.map(item =>
`<li><a href="${item.link?.url || '#'}" class="font-normal text-[var(--color-st-tropaz)] hover:text-[var(--color-dove-gray)] transition-colors">${item.link?.label}</a></li>`
).join('');
marketingUl.innerHTML = links;
}
// Update marketing articles (行銷放大鏡)
const articlesUl = document.getElementById('marketing-articles');
if (articlesUl && data.navItems?.[1]?.childNavItems) {
const links = data.navItems[1].childNavItems.map(item =>
`<li><a href="${item.link?.url || '#'}" class="font-normal text-[var(--color-st-tropaz)] hover:text-[var(--color-dove-gray)] transition-colors">${item.link?.label}</a></li>`
).join('');
articlesUl.innerHTML = links;
}
} catch (error) {
console.error('Failed to load footer data:', error);
}
}
// Load footer data when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', loadFooterData);
} else {
loadFooterData();
}
</script>

View File

@@ -0,0 +1,171 @@
---
import { Image } from "astro:assets";
// Header component
---
<header class="sticky top-0 z-50 bg-transparent">
<nav class="max-w-5xl mx-auto px-4 py-4">
<ul class="flex items-center justify-between list-none">
<li class="flex-shrink-0">
<a href="/" class="block">
<!-- Uses Astro's optimized Image component for the site logo -->
<Image
src="/enchun-logo.svg"
alt="Enchun Digital Marketing"
class="w-32 h-auto"
width={919}
height={201}
loading="eager"
decoding="async"
/>
</a>
</li>
<li class="hidden md:flex items-center space-x-6" id="desktop-nav">
<!-- Navigation items will be populated by JavaScript -->
</li>
<!-- Mobile menu button -->
<li class="md:hidden">
<button
class="text-[var(--color-enchunblue)] hover:text-[var(--color-enchunblue)]/80"
id="mobile-menu-button"
>
<svg
width="24"
height="24"
viewBox="0 0 36 36"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6"
>
<path
d="M6 27H22.5C23.325 27 24 26.325 24 25.5C24 24.675 23.325 24 22.5 24H6C5.175 24 4.5 24.675 4.5 25.5C4.5 26.325 5.175 27 6 27ZM6 19.5H18C18.825 19.5 19.5 18.825 19.5 18C19.5 17.175 18.825 16.5 18 16.5H6C5.175 16.5 4.5 17.175 4.5 18C4.5 18.825 5.175 19.5 6 19.5ZM4.5 10.5C4.5 11.325 5.175 12 6 12H22.5C23.325 12 24 11.325 24 10.5C24 9.675 23.325 9 22.5 9H6C5.175 9 4.5 9.675 4.5 10.5ZM30.45 22.32L26.13 18L30.45 13.68C30.5889 13.5411 30.699 13.3763 30.7742 13.1948C30.8493 13.0134 30.888 12.8189 30.888 12.6225C30.888 12.4261 30.8493 12.2316 30.7742 12.0502C30.699 11.8687 30.5889 11.7039 30.45 11.565C30.3111 11.4261 30.1463 11.316 29.9648 11.2408C29.7834 11.1657 29.5889 11.127 29.3925 11.127C29.1961 11.127 29.0016 11.1657 28.8202 11.2408C28.6387 11.316 28.4739 11.4261 28.335 11.565L22.95 16.95C22.8109 17.0888 22.7006 17.2536 22.6254 17.4351C22.5501 17.6165 22.5113 17.811 22.5113 18.0075C22.5113 18.204 22.5501 18.3985 22.6254 18.5799C22.7006 18.7614 22.8109 18.9262 22.95 19.065L28.335 24.45C28.92 25.035 29.865 25.035 30.45 24.45C31.02 23.865 31.035 22.905 30.45 22.32V22.32Z"
fill="currentColor"></path>
</svg>
</button>
</li>
</ul>
<!-- Mobile menu -->
<div class="md:hidden hidden" id="mobile-menu">
<ul class="pt-4 pb-2 space-y-2" id="mobile-nav">
<!-- Mobile navigation items will be populated by JavaScript -->
</ul>
</div>
</nav>
</header>
<script>
interface NavItem {
link: {
type: "reference" | "custom";
label: string;
url?: string;
reference?: {
slug: string;
};
newTab?: boolean;
};
}
// Fetch navigation data from Payload CMS
async function fetchNavigation() {
try {
// Use local proxy in development to avoid CORS issues
const apiUrl = `/api/globals/header?depth=2&draft=false&locale=undefined&trash=false`;
const response = await fetch(apiUrl);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data.navItems || [];
} catch (error) {
console.error("Error fetching navigation:", error);
throw error;
}
}
// Generate navigation link HTML
function createNavLink(item: NavItem) {
const { link } = item;
let href = "";
if (link.type === "custom" && link.url) {
href = link.url;
} else if (link.type === "reference" && link.reference?.slug) {
href = `/${link.reference.slug}`;
}
const target = link.newTab
? ' target="_blank" rel="noopener noreferrer"'
: "";
const label = link.label;
// Check if current page matches this link
const currentPath = window.location.pathname;
const isActive =
currentPath === href || (href === "/" && currentPath === "/");
// Add badges for specific items (positioned in top right corner)
let badge = "";
if (label.includes("行銷方案")) {
badge =
'<span class="absolute -top-1 -right-1 bg-red-500 text-white text-[0.5rem] px-1 py-0.5 rounded-full">hot</span>';
} else if (label.includes("行銷放大鏡")) {
badge =
'<span class="absolute -top-1 -right-1 bg-red-500 text-white text-[0.5rem] px-1 py-0.5 rounded-full">new</span>';
}
const containerClass = badge ? "relative inline-block" : "";
const activeClass = isActive ? " nav-active" : "";
return `<a href="${href}" class="${containerClass} text-lg font-normal text-shadow-md hover:text-primary transition-colors px-3 py-2${activeClass}"${target}>${label}${badge}</a>`;
}
// Populate navigation
async function populateNavigation() {
const navItems = await fetchNavigation();
const desktopNav = document.getElementById("desktop-nav");
const mobileNav = document.getElementById("mobile-nav");
if (desktopNav && mobileNav) {
// Clear existing content
desktopNav.innerHTML = "";
mobileNav.innerHTML = "";
// Populate desktop navigation
navItems.forEach((item) => {
const linkHtml = createNavLink(item);
const li = document.createElement("li");
li.innerHTML = linkHtml;
desktopNav.appendChild(li);
});
// Populate mobile navigation
navItems.forEach((item) => {
const linkHtml = createNavLink(item)
.replace("px-3 py-2", "block px-3 py-2")
.replace(
"relative inline-block",
"relative inline-block block",
);
const li = document.createElement("li");
li.innerHTML = linkHtml;
mobileNav.appendChild(li);
});
}
}
// Initialize navigation
populateNavigation();
// Simple mobile menu toggle
const button = document.getElementById("mobile-menu-button");
const menu = document.getElementById("mobile-menu");
if (button && menu) {
button.addEventListener("click", () => {
menu.classList.toggle("hidden");
});
}
</script>

View File

@@ -0,0 +1,195 @@
---
import { Image } from "astro:assets";
interface Props {
desktopVideo: string;
mobileVideo: string;
hideOnDesktop?: boolean;
hideOnMobile?: boolean;
logo?: string;
header: string;
subheader: string;
useWebmFallback?: boolean;
focalPoint?: string;
}
const {
desktopVideo,
mobileVideo,
hideOnDesktop = false,
hideOnMobile = false,
logo,
header,
subheader,
useWebmFallback = true,
focalPoint = "object-right",
} = Astro.props;
// Helper to get base path without extension
const getBasePath = (path: string) => path.replace(/\.(mp4|webm)$/i, "");
// Generate sources based on useWebmFallback
const getSources = (inputPath: string) => {
const basePath = getBasePath(inputPath);
if (useWebmFallback) {
return [
{ src: `${basePath}.webm`, type: "video/webm" },
{ src: `${basePath}.mp4`, type: "video/mp4" },
];
}
return [
{
src: inputPath,
type: inputPath.endsWith(".webm") ? "video/webm" : "video/mp4",
},
];
};
---
<!-- Desktop Video -->
<video
id="desktop-video"
class={`absolute top-0 left-0 w-full h-[100dvh] object-cover z-0 hidden md:block ${focalPoint}`}
autoplay
muted
loop
playsinline
preload="metadata"
>
{
getSources(desktopVideo).map((source) => (
<source src={source.src} type={source.type} />
))
}
</video>
<!-- Mobile Video -->
<video
id="mobile-video"
class={`absolute top-0 left-0 w-full h-[100dvh] object-cover z-0 md:hidden block`}
autoplay
muted
loop
playsinline
preload="metadata"
>
{
getSources(mobileVideo).map((source) => (
<source src={source.src} type={source.type} />
))
}
</video>
<!-- Hero Content Overlay -->
<section
class={`h-[100dvh] -mt-[5rem] flex items-center justify-center relative ${hideOnDesktop ? "hidden md:block" : ""} ${hideOnMobile ? "md:hidden" : ""} z-10 overflow-hidden`}
>
<div
class="absolute top-0 left-0 w-full h-full bg-gradient-to-r from-black/80 to-black/0 flex items-center justify-center"
>
<div class="text-white max-w-6xl w-full p-8">
{
logo && (
<div class="flex items-center justify-start mb-6">
<Image
height={182}
width={237}
src={logo}
alt="enchun-ogo"
class="hidden md:block w-32 h-auto mr-8"
/>
<div class="flex flex-col items-start justify-start ">
<h1 class="text-2xl md:text-6xl text-start leading-tight font-extrabold mb-3 whitespace-break-spaces">
{header}
</h1>
<p class="text-xs md:text-3xl font-light mb-4 leading-relaxed whitespace-nowrap">
{subheader}
</p>
</div>
</div>
)
}
{
!logo && (
<div class="flex flex-col items-start">
<h1 class="text-2xl md:text-6xl text-start leading-tight font-extrabold mb-3 whitespace-break-spaces">
{header}
</h1>
<p class="text-xs md:text-3xl font-light mb-4 leading-relaxed whitespace-nowrap">
{subheader}
</p>
</div>
)
}
</div>
</div>
</section>
<script>
// Enhanced mobile/desktop detection and video loading
function initVideoHero() {
const desktopVideo = document.getElementById(
"desktop-video",
) as HTMLVideoElement;
const mobileVideo = document.getElementById(
"mobile-video",
) as HTMLVideoElement;
if (!desktopVideo || !mobileVideo) return;
// Function to check if we're on mobile
const isMobile = () => window.innerWidth < 768;
// Function to switch videos based on device
const switchVideos = () => {
const mobile = isMobile();
if (mobile) {
// On mobile, hide desktop video, show mobile video
desktopVideo.style.display = "none";
mobileVideo.style.display = "block";
} else {
// On desktop, show desktop video, hide mobile video
desktopVideo.style.display = "block";
mobileVideo.style.display = "none";
}
};
// Initial switch
switchVideos();
// Listen for resize events
window.addEventListener("resize", () => {
switchVideos();
});
// Handle video loading errors
[desktopVideo, mobileVideo].forEach((video) => {
video.addEventListener("error", (e) => {
console.warn("Video failed to load:", video.src);
// Could fallback to static image here
});
});
// Preload videos when they're hidden to improve switching
const preloadVideos = () => {
[desktopVideo, mobileVideo].forEach((video) => {
if (video.style.display === "none") {
video.load();
}
});
};
// Preload on load
window.addEventListener("load", preloadVideos);
}
// Initialize when DOM is ready
document.addEventListener("DOMContentLoaded", initVideoHero);
// Also initialize immediately if DOM is already ready
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initVideoHero);
} else {
initVideoHero();
}
</script>

View File

@@ -0,0 +1,80 @@
---
// Admin layout for protected pages
---
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Admin - 恩群數位行銷</title>
<meta name="description" content="Admin panel for Enchun Digital Marketing" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
</head>
<body>
<header class="admin-header">
<nav class="admin-nav">
<div class="admin-nav-brand">
<a href="/admin/dashboard">Admin Panel</a>
</div>
<ul class="admin-nav-links">
<li><a href="/admin/dashboard">Dashboard</a></li>
<li><a href="/admin/cms">CMS</a></li>
<li><button id="logout-btn">Logout</button></li>
</ul>
</nav>
</header>
<main class="admin-main">
<slot />
</main>
</body>
</html>
<script>
// Simple logout handler
document.getElementById('logout-btn')?.addEventListener('click', async () => {
// Call logout API or redirect
window.location.href = 'https://cms.enchun.tw/admin/logout';
});
</script>
<style>
.admin-header {
background: #333;
color: white;
padding: 10px 0;
}
.admin-nav {
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
}
.admin-nav-brand a {
color: white;
text-decoration: none;
font-weight: bold;
}
.admin-nav-links {
display: flex;
list-style: none;
gap: 20px;
}
.admin-nav-links a {
color: white;
text-decoration: none;
}
.admin-nav-links button {
background: #555;
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
}
.admin-main {
padding: 20px;
min-height: calc(100vh - 60px);
}
</style>

View File

@@ -0,0 +1,41 @@
---
import '../styles/tailwind.css';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
// Main layout for the site
---
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>恩群數位行銷</title>
<meta name="description" content="恩群數位累積多年廣告行銷操作經驗,擁有全方位行銷人才,讓我們可以為客戶精準的規劃每一分廣告預算,讓你的品牌深入人心。" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@300;400;500;600;700&display=swap" rel="stylesheet">
</head>
<body class="bg-background text-text font-sans min-h-screen flex flex-col">
<Header />
<main class="flex-1">
<slot />
</main>
<Footer />
</body>
</html>
<style>
body {
font-family: var(--font-family-sans);
margin: 0;
min-height: 100vh;
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
</style>

View File

@@ -0,0 +1,32 @@
import { defineMiddleware } from 'astro:middleware';
import { authService } from './services/auth';
export const onRequest = defineMiddleware(async (context, next) => {
const { url, cookies, redirect } = context;
// Check if the route is under /admin/
if (url.pathname.startsWith('/admin/')) {
// Get token from cookie
const token = cookies.get('payload-token')?.value;
if (!token) {
// Redirect to CMS login subdomain
return redirect('https://cms.enchun.tw/admin/login');
}
// Validate token
authService.token = token;
const user = await authService.getCurrentUser();
if (!user) {
// Token invalid, redirect to login
cookies.delete('payload-token');
return redirect('https://cms.enchun.tw/admin/login');
}
// User authenticated, proceed
// Could add role checks here if needed
}
return next();
});

View File

@@ -0,0 +1,31 @@
---
import Layout from '../layouts/Layout.astro';
---
<Layout>
<section class="about-section">
<div class="container">
<h1>關於恩群</h1>
<div class="prose prose-custom max-w-none">
<p>恩群數位行銷有限公司成立於2018年專注於數位行銷服務。</p>
<p>我們擁有豐富的廣告行銷操作經驗,提供全方位行銷解決方案。</p>
<!-- Add more content from HTML -->
</div>
</div>
</section>
</Layout>
<style>
.about-section {
padding: 40px 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
h1 {
text-align: center;
margin-bottom: 30px;
}
</style>

View File

@@ -0,0 +1,30 @@
---
import AdminLayout from '../../layouts/AdminLayout.astro';
---
<AdminLayout>
<div class="cms-section">
<h1>Payload CMS</h1>
<p>The CMS is hosted on a separate subdomain for security.</p>
<a href="https://cms.enchun.tw/admin" class="btn" target="_blank">Open CMS</a>
</div>
</AdminLayout>
<style>
.cms-section {
text-align: center;
padding: 40px 0;
}
.btn {
display: inline-block;
background: #007bff;
color: white;
padding: 15px 30px;
text-decoration: none;
border-radius: 4px;
font-size: 18px;
}
.btn:hover {
background: #0056b3;
}
</style>

View File

@@ -0,0 +1,56 @@
---
import AdminLayout from '../../layouts/AdminLayout.astro';
---
<AdminLayout>
<div class="dashboard">
<h1>Admin Dashboard</h1>
<div class="dashboard-grid">
<div class="dashboard-card">
<h2>Content Management</h2>
<p>Manage blog posts, portfolios, and categories.</p>
<a href="/admin/cms" class="btn">Go to CMS</a>
</div>
<div class="dashboard-card">
<h2>Analytics</h2>
<p>View site analytics and performance metrics.</p>
<a href="#" class="btn">View Analytics</a>
</div>
</div>
</div>
</AdminLayout>
<style>
.dashboard {
max-width: 1200px;
margin: 0 auto;
}
h1 {
margin-bottom: 30px;
}
.dashboard-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
.dashboard-card {
border: 1px solid #ddd;
padding: 20px;
border-radius: 8px;
background: #f9f9f9;
}
.dashboard-card h2 {
margin-top: 0;
}
.btn {
display: inline-block;
background: #007bff;
color: white;
padding: 10px 15px;
text-decoration: none;
border-radius: 4px;
}
.btn:hover {
background: #0056b3;
}
</style>

View File

@@ -0,0 +1,6 @@
---
// Admin login page - redirects to CMS subdomain
---
<meta http-equiv="refresh" content="0; url=https://cms.enchun.tw/admin/login" />
<p>Redirecting to login...</p>

View File

@@ -0,0 +1,85 @@
---
import Layout from '../layouts/Layout.astro';
---
<Layout>
<section class="contact-section">
<div class="container">
<h1>聯絡我們</h1>
<form id="contact-form">
<div class="form-group">
<label for="name">姓名</label>
<input type="text" id="name" name="name" required />
</div>
<div class="form-group">
<label for="email">電子郵件</label>
<input type="email" id="email" name="email" required />
</div>
<div class="form-group">
<label for="message">訊息</label>
<textarea id="message" name="message" required></textarea>
</div>
<button type="submit">送出</button>
</form>
<div class="contact-info">
<p>諮詢電話: 02 5570 0527</p>
<p>電子郵件: <a href="mailto:enchuntaiwan@gmail.com">enchuntaiwan@gmail.com</a></p>
</div>
</div>
</section>
</Layout>
<script>
// Basic form handler - would integrate with Cloudflare Worker
document.getElementById('contact-form')?.addEventListener('submit', async (e) => {
e.preventDefault();
// Submit to Cloudflare Worker
alert('Form submitted (placeholder)');
});
</script>
<style>
.contact-section {
padding: 40px 0;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 0 20px;
}
h1 {
text-align: center;
margin-bottom: 30px;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 5px;
}
input, textarea {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
textarea {
height: 150px;
}
button {
background: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #0056b3;
}
.contact-info {
margin-top: 40px;
text-align: center;
}
</style>

View File

@@ -1,16 +1,66 @@
--- ---
import '../styles/tailwind.css'; import Layout from "../layouts/Layout.astro";
import VideoHero from "../components/videoHero.astro";
--- ---
<html lang="en"> <Layout>
<head> <!-- Hero Section -->
<meta charset="utf-8" /> <VideoHero
<title>enchun.tw</title> desktopVideo="/video/enchun-hero-background-video.mp4"
</head> mobileVideo="/video/enchun-hero-background-video.webm"
<body class="bg-surface text-text"> logo="/enchun-logo-full.svg"
<main class="mx-auto flex min-h-screen max-w-4xl flex-col items-center justify-center gap-6 px-4 text-center"> header="創造企業更多發展的可能性\n是我們的使命"
<h1 class="text-4xl font-semibold text-primary">enchun.tw migration scaffold</h1> subheader="Its our destiny to create possibilities for your business."
<p class="text-lg text-secondary">Astro SSR frontend is ready for development.</p> />
</main>
</body> <!-- Services Section -->
</html> <section class="py-16 bg-surface">
<div class="max-w-6xl mx-auto px-4">
<h2 class="text-3xl font-bold text-center text-text mb-12">
我們的服務
</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<div class="bg-white p-6 rounded-lg shadow-md">
<h3 class="text-xl font-semibold text-primary mb-4">
Google Ads
</h3>
<p class="text-text">
專業的Google廣告投放服務幫助您的品牌觸及目標客戶。
</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md">
<h3 class="text-xl font-semibold text-primary mb-4">
社群行銷
</h3>
<p class="text-text">
全方位社群媒體經營,從內容策劃到數據分析,一站式服務。
</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md">
<h3 class="text-xl font-semibold text-primary mb-4">
網站設計
</h3>
<p class="text-text">
現代化響應式網站設計,提升品牌形象和用戶體驗。
</p>
</div>
</div>
</div>
</section>
<!-- About Section -->
<section class="py-16">
<div class="max-w-6xl mx-auto px-4 text-center">
<h2 class="text-3xl font-bold text-text mb-8">關於恩群</h2>
<p class="text-lg text-text max-w-3xl mx-auto">
恩群數位行銷團隊擁有豐富的數位行銷經驗,我們相信在地化優先、高投資轉換率、數據優先、關係優於銷售。
每一個客戶都是我們重視的夥伴,我們珍惜與客戶的合作關係。
</p>
<a
href="/about-enchun"
class="inline-block mt-6 bg-primary text-white px-6 py-3 rounded-lg font-semibold hover:bg-primary/90 transition-colors"
>了解更多</a
>
</div>
</section>
</Layout>

View File

@@ -0,0 +1,43 @@
---
import Layout from '../layouts/Layout.astro';
---
<Layout>
<section class="solutions-section">
<div class="container">
<h1>行銷方案</h1>
<p>我們提供多樣化的行銷方案,幫助您的品牌深入人心。</p>
<ul>
<li>Google 商家關鍵字</li>
<li>Google Ads</li>
<li>社群代操</li>
<li>論壇行銷</li>
<li>網紅行銷</li>
<li>形象影片</li>
</ul>
</div>
</section>
</Layout>
<style>
.solutions-section {
padding: 40px 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
h1 {
text-align: center;
margin-bottom: 30px;
}
ul {
list-style: none;
padding: 0;
}
li {
padding: 10px 0;
border-bottom: 1px solid #eee;
}
</style>

View File

@@ -0,0 +1,61 @@
---
import Layout from '../layouts/Layout.astro';
// Placeholder for blog posts - would fetch from CMS
const posts = [
{ slug: 'en-qun-shu-wei-zui-xin-gong-gao', title: '恩群數位最新公告', date: '2023-01-01' },
{ slug: 'google-xiao-xue-tang', title: 'Google小學堂', date: '2023-01-02' },
// Add more
];
---
<Layout>
<section class="news-section">
<div class="container">
<h1>行銷放大鏡</h1>
<div class="posts-grid">
{posts.map(post => (
<article class="post-card">
<h2><a href={`/wen-zhang-fen-lei/${post.slug}`}>{post.title}</a></h2>
<p>{post.date}</p>
</article>
))}
</div>
</div>
</section>
</Layout>
<style>
.news-section {
padding: 40px 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
h1 {
text-align: center;
margin-bottom: 30px;
}
.posts-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
}
.post-card {
border: 1px solid #ddd;
padding: 20px;
border-radius: 8px;
}
.post-card h2 {
margin-top: 0;
}
.post-card a {
text-decoration: none;
color: #333;
}
.post-card a:hover {
color: #007bff;
}
</style>

View File

@@ -0,0 +1,28 @@
---
import Layout from '../layouts/Layout.astro';
---
<Layout>
<section class="teams-section">
<div class="container">
<h1>恩群大本營</h1>
<p>認識我們的團隊成員。</p>
<!-- Team members would be listed here -->
</div>
</section>
</Layout>
<style>
.teams-section {
padding: 40px 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
h1 {
text-align: center;
margin-bottom: 30px;
}
</style>

View File

@@ -0,0 +1,52 @@
---
import Layout from '../../layouts/Layout.astro';
export async function getStaticPaths() {
// Portfolio slugs from sitemap
const slugs = [
'web-design-project-2',
'web-design-project-3',
'web-design-project-4',
'web-design-project-5'
];
return slugs.map(slug => ({
params: { slug },
props: { slug }
}));
}
const { slug } = Astro.props;
// Placeholder content
const project = {
title: 'Web Design Project',
description: 'Project description...',
images: []
};
---
<Layout>
<section class="project-section">
<div class="container">
<h1>{project.title}</h1>
<p>{project.description}</p>
<!-- Images and details -->
</div>
</section>
</Layout>
<style>
.project-section {
padding: 40px 0;
}
.container {
max-width: 1000px;
margin: 0 auto;
padding: 0 20px;
}
h1 {
text-align: center;
margin-bottom: 30px;
}
</style>

View File

@@ -0,0 +1,57 @@
---
import Layout from '../layouts/Layout.astro';
// Placeholder portfolios
const portfolios = [
{ slug: 'web-design-project-2', title: 'Project 2', description: 'Description...' },
// Add more
];
---
<Layout>
<section class="portfolio-section">
<div class="container">
<h1>網站設計作品</h1>
<div class="portfolio-grid">
{portfolios.map(item => (
<div class="portfolio-item">
<h2><a href={`/webdesign-profolio/${item.slug}`}>{item.title}</a></h2>
<p>{item.description}</p>
</div>
))}
</div>
</div>
</section>
</Layout>
<style>
.portfolio-section {
padding: 40px 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
h1 {
text-align: center;
margin-bottom: 30px;
}
.portfolio-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
}
.portfolio-item {
border: 1px solid #ddd;
padding: 20px;
border-radius: 8px;
}
.portfolio-item a {
text-decoration: none;
color: #333;
}
.portfolio-item a:hover {
color: #007bff;
}
</style>

View File

@@ -0,0 +1,79 @@
---
import Layout from '../../layouts/Layout.astro';
export async function getStaticPaths() {
// Category slugs
const slugs = [
'en-qun-shu-wei-zui-xin-gong-gao',
'xing-xiao-shi-shi-zui-qian-xian',
'meta-xiao-xue-tang',
'google-xiao-xue-tang'
];
return slugs.map(slug => ({
params: { slug },
props: { slug }
}));
}
const { slug } = Astro.props;
// Placeholder - would fetch category and posts from CMS
const category = {
name: 'Category Name',
posts: [
{ slug: 'post1', title: 'Post 1', date: '2023-01-01' }
]
};
---
<Layout>
<section class="category-section">
<div class="container">
<h1>{category.name}</h1>
<div class="posts-list">
{category.posts.map(post => (
<article class="post-item">
<h2><a href={`/xing-xiao-fang-da-jing/${post.slug}`}>{post.title}</a></h2>
<p>{post.date}</p>
</article>
))}
</div>
</div>
</section>
</Layout>
<style>
.category-section {
padding: 40px 0;
}
.container {
max-width: 1000px;
margin: 0 auto;
padding: 0 20px;
}
h1 {
text-align: center;
margin-bottom: 30px;
}
.posts-list {
display: flex;
flex-direction: column;
gap: 20px;
}
.post-item {
border: 1px solid #ddd;
padding: 20px;
border-radius: 8px;
}
.post-item h2 {
margin-top: 0;
}
.post-item a {
text-decoration: none;
color: #333;
}
.post-item a:hover {
color: #007bff;
}
</style>

View File

@@ -0,0 +1,66 @@
---
import Layout from '../../layouts/Layout.astro';
export async function getStaticPaths() {
// Placeholder slugs - would fetch from CMS
const slugs = [
'2-zhao-yao-kong-xiao-fei-zhe-de-xin',
'2022-jie-qing-xing-xiao-quan-gong-lue',
// Add all from sitemap
];
return slugs.map(slug => ({
params: { slug },
props: { slug }
}));
}
const { slug } = Astro.props;
// Placeholder content - would fetch from CMS
const post = {
title: 'Sample Post Title',
date: 'January 20, 2022',
content: 'Sample content...'
};
---
<Layout>
<section class="post-section">
<div class="container">
<a href="/news" class="back-link">回到文章列表</a>
<article>
<h1>{post.title}</h1>
<p class="post-date">文章發布日期:{post.date}</p>
<div class="post-content prose prose-custom max-w-none">
<p>{post.content}</p>
<!-- More content would be rendered here with markdown -->
</div>
</article>
</div>
</section>
</Layout>
<style>
.post-section {
padding: 40px 0;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 0 20px;
}
.back-link {
display: inline-block;
margin-bottom: 20px;
color: #007bff;
text-decoration: none;
}
.post-date {
color: #666;
margin-bottom: 20px;
}
.post-content {
/* Prose styles handle typography */
}
</style>

Some files were not shown because too many files have changed in this diff Show More