Compare commits
3 Commits
7f61b58880
...
6b0cb56046
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b0cb56046 | |||
| c2d4c8d0a0 | |||
|
|
cf0f779ad4 |
101
.claude/commands/analyze.md
Normal file
101
.claude/commands/analyze.md
Normal 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
158
.claude/commands/clarify.md
Normal 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 multiple‑choice selection (2–5 distinct, mutually exclusive options), OR
|
||||
* A one-word / short‑phrase 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 multiple‑choice 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 short‑answer 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
|
||||
@@ -11,6 +11,7 @@ $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
|
||||
|
||||
@@ -11,6 +11,7 @@ $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
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,6 +5,7 @@
|
||||
# Build output
|
||||
/dist
|
||||
/build
|
||||
**/.astro
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
101
.kilocode/workflows/analyze.md
Normal file
101
.kilocode/workflows/analyze.md
Normal 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
.kilocode/workflows/clarify.md
Normal file
158
.kilocode/workflows/clarify.md
Normal 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 multiple‑choice selection (2–5 distinct, mutually exclusive options), OR
|
||||
* A one-word / short‑phrase 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 multiple‑choice 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 short‑answer 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
|
||||
73
.kilocode/workflows/constitution.md
Normal file
73
.kilocode/workflows/constitution.md
Normal 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 non‑negotiable 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.
|
||||
56
.kilocode/workflows/implement.md
Normal file
56
.kilocode/workflows/implement.md
Normal 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
.kilocode/workflows/plan.md
Normal file
43
.kilocode/workflows/plan.md
Normal 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.
|
||||
21
.kilocode/workflows/specify.md
Normal file
21
.kilocode/workflows/specify.md
Normal 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.
|
||||
62
.kilocode/workflows/tasks.md
Normal file
62
.kilocode/workflows/tasks.md
Normal 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.
|
||||
101
.opencode/command/analyze.md
Normal file
101
.opencode/command/analyze.md
Normal 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
.opencode/command/clarify.md
Normal file
158
.opencode/command/clarify.md
Normal 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 multiple‑choice selection (2–5 distinct, mutually exclusive options), OR
|
||||
* A one-word / short‑phrase 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 multiple‑choice 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 short‑answer 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
|
||||
73
.opencode/command/constitution.md
Normal file
73
.opencode/command/constitution.md
Normal 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 non‑negotiable 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.
|
||||
56
.opencode/command/implement.md
Normal file
56
.opencode/command/implement.md
Normal 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
43
.opencode/command/plan.md
Normal 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.
|
||||
21
.opencode/command/specify.md
Normal file
21
.opencode/command/specify.md
Normal 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.
|
||||
62
.opencode/command/tasks.md
Normal file
62
.opencode/command/tasks.md
Normal 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
1
.roo/mcp.json
Normal file
@@ -0,0 +1 @@
|
||||
{"mcpServers":{}}
|
||||
72
.spec-workflow/config.example.toml
Normal file
72
.spec-workflow/config.example.toml
Normal 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
|
||||
96
.spec-workflow/templates/design-template.md
Normal file
96
.spec-workflow/templates/design-template.md
Normal 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]
|
||||
51
.spec-workflow/templates/product-template.md
Normal file
51
.spec-workflow/templates/product-template.md
Normal 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]
|
||||
50
.spec-workflow/templates/requirements-template.md
Normal file
50
.spec-workflow/templates/requirements-template.md
Normal 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]
|
||||
145
.spec-workflow/templates/structure-template.md
Normal file
145
.spec-workflow/templates/structure-template.md
Normal 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
|
||||
139
.spec-workflow/templates/tasks-template.md
Normal file
139
.spec-workflow/templates/tasks-template.md
Normal 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_
|
||||
99
.spec-workflow/templates/tech-template.md
Normal file
99
.spec-workflow/templates/tech-template.md
Normal 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]
|
||||
64
.spec-workflow/user-templates/README.md
Normal file
64
.spec-workflow/user-templates/README.md
Normal 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
|
||||
@@ -82,14 +82,20 @@ source "$SCRIPT_DIR/common.sh"
|
||||
eval $(get_feature_paths)
|
||||
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
|
||||
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"
|
||||
if $JSON_MODE; then
|
||||
# Minimal JSON paths payload (no validation performed)
|
||||
printf '{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS":"%s"}\n' \
|
||||
"$REPO_ROOT" "$CURRENT_BRANCH" "$FEATURE_DIR" "$FEATURE_SPEC" "$IMPL_PLAN" "$TASKS"
|
||||
else
|
||||
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
|
||||
fi
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ fi
|
||||
FEATURE_DIR="$SPECS_DIR/$BRANCH_NAME"
|
||||
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"
|
||||
if [ -f "$TEMPLATE" ]; then cp "$TEMPLATE" "$SPEC_FILE"; else touch "$SPEC_FILE"; fi
|
||||
|
||||
|
||||
@@ -30,12 +30,12 @@
|
||||
#
|
||||
# 5. Multi-Agent Support
|
||||
# - 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
|
||||
# - Creates default Claude file if no agent files exist
|
||||
#
|
||||
# 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
|
||||
|
||||
set -e
|
||||
@@ -69,6 +69,7 @@ WINDSURF_FILE="$REPO_ROOT/.windsurf/rules/specify-rules.md"
|
||||
KILOCODE_FILE="$REPO_ROOT/.kilocode/rules/specify-rules.md"
|
||||
AUGGIE_FILE="$REPO_ROOT/.augment/rules/specify-rules.md"
|
||||
ROO_FILE="$REPO_ROOT/.roo/rules/specify-rules.md"
|
||||
Q_FILE="$REPO_ROOT/AGENTS.md"
|
||||
|
||||
# Template file
|
||||
TEMPLATE_FILE="$REPO_ROOT/.specify/templates/agent-file-template.md"
|
||||
@@ -580,9 +581,12 @@ update_specific_agent() {
|
||||
roo)
|
||||
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 "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
|
||||
;;
|
||||
esac
|
||||
@@ -641,6 +645,11 @@ update_all_existing_agents() {
|
||||
update_agent_file "$ROO_FILE" "Roo Code"
|
||||
found_agent=true
|
||||
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 [[ "$found_agent" == false ]]; then
|
||||
@@ -665,7 +674,7 @@ print_summary() {
|
||||
fi
|
||||
|
||||
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]"
|
||||
}
|
||||
|
||||
#==============================================================================
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
1. Load feature spec from Input path
|
||||
→ If not found: ERROR "No feature spec at {path}"
|
||||
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
|
||||
3. Fill the Constitution Check section based on the content of the constitution document.
|
||||
4. Evaluate Constitution Check section below
|
||||
@@ -18,7 +18,7 @@
|
||||
→ Update Progress Tracking: Initial Constitution Check
|
||||
5. Execute Phase 0 → research.md
|
||||
→ 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
|
||||
→ If new violations: Refactor design, return to Phase 1
|
||||
→ Update Progress Tracking: Post-Design Constitution Check
|
||||
@@ -63,8 +63,14 @@ specs/[###-feature]/
|
||||
```
|
||||
|
||||
### 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/
|
||||
├── models/
|
||||
├── services/
|
||||
@@ -76,7 +82,7 @@ tests/
|
||||
├── integration/
|
||||
└── unit/
|
||||
|
||||
# Option 2: Web application (when "frontend" + "backend" detected)
|
||||
# [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected)
|
||||
backend/
|
||||
├── src/
|
||||
│ ├── models/
|
||||
@@ -91,15 +97,16 @@ frontend/
|
||||
│ └── services/
|
||||
└── tests/
|
||||
|
||||
# Option 3: Mobile + API (when "iOS/Android" detected)
|
||||
# [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected)
|
||||
api/
|
||||
└── [same as backend above]
|
||||
|
||||
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
|
||||
1. **Extract unknowns from Technical Context** above:
|
||||
@@ -145,7 +152,7 @@ ios/ or android/
|
||||
- Quickstart test = story validation steps
|
||||
|
||||
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.
|
||||
- If exists: Add only NEW tech from current plan
|
||||
- Preserve manual additions between markers
|
||||
|
||||
@@ -63,7 +63,11 @@ export default buildConfig({
|
||||
url: process.env.DATABASE_URI || '',
|
||||
}),
|
||||
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],
|
||||
plugins: [
|
||||
...plugins,
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
import tailwindcssAnimate from 'tailwindcss-animate'
|
||||
import typography from '@tailwindcss/typography'
|
||||
|
||||
import tailwindcssAnimate from 'tailwindcss-animate'
|
||||
import typography from '@tailwindcss/typography'
|
||||
import sharedConfig from '@enchun/shared/tailwind-config-v3'
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
const config = {
|
||||
...sharedConfig,
|
||||
content: [
|
||||
'./pages/**/*.{ts,tsx}',
|
||||
'./components/**/*.{ts,tsx}',
|
||||
'./app/**/*.{ts,tsx}',
|
||||
'./src/**/*.{ts,tsx}',
|
||||
...sharedConfig.content,
|
||||
],
|
||||
darkMode: ['selector', '[data-theme="dark"]'],
|
||||
plugins: [tailwindcssAnimate, typography],
|
||||
|
||||
1
apps/frontend/.astro/content-assets.mjs
Normal file
1
apps/frontend/.astro/content-assets.mjs
Normal file
@@ -0,0 +1 @@
|
||||
export default new Map();
|
||||
1
apps/frontend/.astro/content-modules.mjs
Normal file
1
apps/frontend/.astro/content-modules.mjs
Normal file
@@ -0,0 +1 @@
|
||||
export default new Map();
|
||||
1
apps/frontend/.astro/data-store.json
Normal file
1
apps/frontend/.astro/data-store.json
Normal 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\":false,\"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\"}}}"]
|
||||
8
apps/frontend/.env.example
Normal file
8
apps/frontend/.env.example
Normal 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
|
||||
72
apps/frontend/.spec-workflow/config.example.toml
Normal file
72
apps/frontend/.spec-workflow/config.example.toml
Normal 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
|
||||
96
apps/frontend/.spec-workflow/templates/design-template.md
Normal file
96
apps/frontend/.spec-workflow/templates/design-template.md
Normal 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]
|
||||
51
apps/frontend/.spec-workflow/templates/product-template.md
Normal file
51
apps/frontend/.spec-workflow/templates/product-template.md
Normal 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]
|
||||
@@ -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]
|
||||
145
apps/frontend/.spec-workflow/templates/structure-template.md
Normal file
145
apps/frontend/.spec-workflow/templates/structure-template.md
Normal 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
|
||||
139
apps/frontend/.spec-workflow/templates/tasks-template.md
Normal file
139
apps/frontend/.spec-workflow/templates/tasks-template.md
Normal 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_
|
||||
99
apps/frontend/.spec-workflow/templates/tech-template.md
Normal file
99
apps/frontend/.spec-workflow/templates/tech-template.md
Normal 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]
|
||||
64
apps/frontend/.spec-workflow/user-templates/README.md
Normal file
64
apps/frontend/.spec-workflow/user-templates/README.md
Normal 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
|
||||
@@ -1,3 +1,35 @@
|
||||
# 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.
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
import { defineConfig } from 'astro/config';
|
||||
import cloudflare from '@astrojs/cloudflare';
|
||||
import tailwind from '@astrojs/tailwind';
|
||||
// @ts-check
|
||||
import { defineConfig } from "astro/config";
|
||||
import cloudflare from "@astrojs/cloudflare";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
output: 'server',
|
||||
output: "server",
|
||||
adapter: cloudflare(),
|
||||
integrations: [tailwind()],
|
||||
vite: {
|
||||
plugins: [tailwindcss()],
|
||||
server: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'https://enchun-admin.anlstudio.cc',
|
||||
changeOrigin: true,
|
||||
secure: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
typescript: {
|
||||
strict: true
|
||||
}
|
||||
strict: true,
|
||||
},
|
||||
});
|
||||
|
||||
3
apps/frontend/dev.vars
Normal file
3
apps/frontend/dev.vars
Normal 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
|
||||
@@ -5,19 +5,22 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"dev:pages": "wrangler pages dev --compatibility-date=2024-01-01",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"check": "astro check"
|
||||
"check": "astro check",
|
||||
"deploy": "wrangler pages deploy dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/cloudflare": "^9.0.0",
|
||||
"@astrojs/tailwind": "^5.0.0",
|
||||
"astro": "^4.0.0",
|
||||
"@astrojs/cloudflare": "^12.6.9",
|
||||
"@tailwindcss/vite": "^4.1.14",
|
||||
"astro": "^5.14.1",
|
||||
"better-auth": "^1.3.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"autoprefixer": "^10.4.0",
|
||||
"tailwindcss": "^3.4.0",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"typescript": "^5.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {}
|
||||
}
|
||||
};
|
||||
8
apps/frontend/public/enchun-logo.svg
Normal file
8
apps/frontend/public/enchun-logo.svg
Normal 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 |
10
apps/frontend/public/fb-icon.svg
Normal file
10
apps/frontend/public/fb-icon.svg
Normal 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 |
3
apps/frontend/public/menu-icon.svg
Normal file
3
apps/frontend/public/menu-icon.svg
Normal 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 |
25
apps/frontend/redirects.js
Normal file
25
apps/frontend/redirects.js
Normal 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;
|
||||
90
apps/frontend/src/components/Footer.astro
Normal file
90
apps/frontend/src/components/Footer.astro
Normal 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>
|
||||
|
||||
149
apps/frontend/src/components/Header.astro
Normal file
149
apps/frontend/src/components/Header.astro
Normal file
@@ -0,0 +1,149 @@
|
||||
---
|
||||
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"/>
|
||||
</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>
|
||||
80
apps/frontend/src/layouts/AdminLayout.astro
Normal file
80
apps/frontend/src/layouts/AdminLayout.astro
Normal 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>
|
||||
41
apps/frontend/src/layouts/Layout.astro
Normal file
41
apps/frontend/src/layouts/Layout.astro
Normal 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>
|
||||
32
apps/frontend/src/middleware.ts
Normal file
32
apps/frontend/src/middleware.ts
Normal 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();
|
||||
});
|
||||
31
apps/frontend/src/pages/about-enchun.astro
Normal file
31
apps/frontend/src/pages/about-enchun.astro
Normal 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>
|
||||
30
apps/frontend/src/pages/admin/cms.astro
Normal file
30
apps/frontend/src/pages/admin/cms.astro
Normal 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>
|
||||
56
apps/frontend/src/pages/admin/dashboard.astro
Normal file
56
apps/frontend/src/pages/admin/dashboard.astro
Normal 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>
|
||||
6
apps/frontend/src/pages/admin/login.astro
Normal file
6
apps/frontend/src/pages/admin/login.astro
Normal 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>
|
||||
85
apps/frontend/src/pages/contact-us.astro
Normal file
85
apps/frontend/src/pages/contact-us.astro
Normal 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>
|
||||
@@ -1,16 +1,47 @@
|
||||
---
|
||||
import '../styles/tailwind.css';
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>enchun.tw</title>
|
||||
</head>
|
||||
<body class="bg-surface text-text">
|
||||
<main class="mx-auto flex min-h-screen max-w-4xl flex-col items-center justify-center gap-6 px-4 text-center">
|
||||
<h1 class="text-4xl font-semibold text-primary">enchun.tw migration scaffold</h1>
|
||||
<p class="text-lg text-secondary">Astro SSR frontend is ready for development.</p>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
<Layout>
|
||||
<!-- Hero Section -->
|
||||
<section class="bg-gradient-to-r from-primary to-secondary text-white py-20">
|
||||
<div class="max-w-6xl mx-auto px-4 text-center">
|
||||
<h1 class="text-4xl md:text-6xl font-bold mb-6">恩群數位行銷</h1>
|
||||
<p class="text-xl md:text-2xl mb-8">累積多年廣告行銷操作經驗,全方位行銷人才,為您精準規劃每一分廣告預算</p>
|
||||
<a href="/contact-us" class="bg-white text-primary px-8 py-3 rounded-lg font-semibold hover:bg-gray-100 transition-colors">聯絡我們</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Services Section -->
|
||||
<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>
|
||||
|
||||
43
apps/frontend/src/pages/marketing-solutions.astro
Normal file
43
apps/frontend/src/pages/marketing-solutions.astro
Normal 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>
|
||||
61
apps/frontend/src/pages/news.astro
Normal file
61
apps/frontend/src/pages/news.astro
Normal 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>
|
||||
28
apps/frontend/src/pages/teams.astro
Normal file
28
apps/frontend/src/pages/teams.astro
Normal 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>
|
||||
52
apps/frontend/src/pages/webdesign-profolio/[slug].astro
Normal file
52
apps/frontend/src/pages/webdesign-profolio/[slug].astro
Normal 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>
|
||||
57
apps/frontend/src/pages/website-portfolio.astro
Normal file
57
apps/frontend/src/pages/website-portfolio.astro
Normal 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>
|
||||
79
apps/frontend/src/pages/wen-zhang-fen-lei/[slug].astro
Normal file
79
apps/frontend/src/pages/wen-zhang-fen-lei/[slug].astro
Normal 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>
|
||||
66
apps/frontend/src/pages/xing-xiao-fang-da-jing/[slug].astro
Normal file
66
apps/frontend/src/pages/xing-xiao-fang-da-jing/[slug].astro
Normal 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>
|
||||
114
apps/frontend/src/services/auth.ts
Normal file
114
apps/frontend/src/services/auth.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
// Payload CMS Authentication Service
|
||||
// Handles authentication with Payload CMS backend
|
||||
|
||||
// Get API base URL from wrangler.toml configuration
|
||||
function getApiBaseUrl() {
|
||||
// Check for environment-specific URLs from wrangler.toml
|
||||
if (typeof process !== 'undefined' && process.env) {
|
||||
return process.env.PAYLOAD_CMS_URL;
|
||||
}
|
||||
// Fallback for client-side or when process.env is not available
|
||||
return import.meta.env.PUBLIC_PAYLOAD_CMS_URL || 'https://enchun-admin.anlstudio.cc';
|
||||
}
|
||||
|
||||
const PAYLOAD_URL = getApiBaseUrl();
|
||||
const PAYLOAD_API_KEY = import.meta.env.PAYLOAD_CMS_API_KEY;
|
||||
|
||||
export interface User {
|
||||
id: string;
|
||||
email: string;
|
||||
role: 'admin' | 'editor';
|
||||
}
|
||||
|
||||
export interface AuthResponse {
|
||||
user: User;
|
||||
token: string;
|
||||
}
|
||||
|
||||
export class AuthService {
|
||||
private token: string | null = null;
|
||||
|
||||
constructor() {
|
||||
// Load token from localStorage or cookie on client
|
||||
if (typeof window !== 'undefined') {
|
||||
this.token = localStorage.getItem('payload-token');
|
||||
}
|
||||
}
|
||||
|
||||
async login(email: string, password: string): Promise<AuthResponse> {
|
||||
const response = await fetch(`${PAYLOAD_URL}/api/users/login`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...(PAYLOAD_API_KEY && { 'Authorization': `Bearer ${PAYLOAD_API_KEY}` }),
|
||||
},
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Login failed');
|
||||
}
|
||||
|
||||
const data: AuthResponse = await response.json();
|
||||
this.token = data.token;
|
||||
|
||||
// Store token
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.setItem('payload-token', data.token);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
async logout(): Promise<void> {
|
||||
this.token = null;
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.removeItem('payload-token');
|
||||
}
|
||||
|
||||
// Optional: Call logout endpoint
|
||||
try {
|
||||
await fetch(`${PAYLOAD_URL}/api/users/logout`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
...(this.token && { 'Authorization': `Bearer ${this.token}` }),
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
// Ignore logout errors
|
||||
}
|
||||
}
|
||||
|
||||
async getCurrentUser(): Promise<User | null> {
|
||||
if (!this.token) return null;
|
||||
|
||||
try {
|
||||
const response = await fetch(`${PAYLOAD_URL}/api/users/me`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.token}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
this.token = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data.user;
|
||||
} catch (error) {
|
||||
this.token = null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
getToken(): string | null {
|
||||
return this.token;
|
||||
}
|
||||
|
||||
isAuthenticated(): boolean {
|
||||
return !!this.token;
|
||||
}
|
||||
}
|
||||
|
||||
export const authService = new AuthService();
|
||||
@@ -1,3 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import "./theme.css";
|
||||
@import "tailwindcss";
|
||||
@config "../../tailwind.config.mjs";
|
||||
|
||||
369
apps/frontend/src/styles/theme.css
Normal file
369
apps/frontend/src/styles/theme.css
Normal file
@@ -0,0 +1,369 @@
|
||||
/* Theme CSS Variables and Custom Styles */
|
||||
|
||||
/* CSS Custom Properties for Theme */
|
||||
:root {
|
||||
/* Color Palette */
|
||||
--color-primary: #1F3A93;
|
||||
--color-secondary: #F39C12;
|
||||
--color-accent: #16A085;
|
||||
--color-enchunblue: #3083BF;
|
||||
--color-background: #FFFFFF;
|
||||
--color-surface: #F7FAFC;
|
||||
--color-text: #1A202C;
|
||||
--color-text-muted: #718096;
|
||||
--color-border: #E2E8F0;
|
||||
/*
|
||||
Purpose:
|
||||
Define Enchun brand color palette as CSS custom properties for easy, semantic access in components.
|
||||
Each color is named by its original key (minus 'www.enchun.tw/') in kebab-case for clarity and maintainability.
|
||||
*/
|
||||
/*
|
||||
Purpose:
|
||||
Define extended Enchun brand color palette as CSS custom properties, all prefixed with --color- for consistency and semantic clarity.
|
||||
This ensures all color variables are easily discoverable and maintainable across the codebase.
|
||||
*/
|
||||
--color-alabaster: #fafafa;
|
||||
--color-alto: #d1d1d1;
|
||||
--color-amber: #ffc107;
|
||||
--color-black: #000000;
|
||||
--color-boston-blue: #3083bf;
|
||||
--color-concrete: #f2f2f2;
|
||||
--color-cream-can: #f6c456;
|
||||
--color-dove-gray: #6b6b6b;
|
||||
--color-dusty-gray: #999999;
|
||||
--color-emperor: #4f4f4f;
|
||||
--color-gray: #878787;
|
||||
--color-killarney: #3c6f50;
|
||||
--color-lucky-point: #171c61;
|
||||
--color-manatee: #939494;
|
||||
--color-mercury: #e3e3e3;
|
||||
--color-mine-shaft: #333333;
|
||||
--color-mine-shaft-60: #222222;
|
||||
--color-nobel: #b6b6b6;
|
||||
--color-oslo-gray: #939494;
|
||||
--color-pomegranate: #f44336;
|
||||
--color-silver: #bdbdbd;
|
||||
--color-silver-chalice: #acacac;
|
||||
--color-st-tropaz: #2b618f;
|
||||
--color-tarawera: #062841;
|
||||
--color-tropical-blue: #c7e4fa;
|
||||
--color-tundora: #4d4d4d;
|
||||
--color-turbo: #ffef00;
|
||||
--color-valencia: #d84038;
|
||||
--color-viking: #67aee1;
|
||||
--color-white: #ffffff;
|
||||
--color-wild-sand: #f6f6f6;
|
||||
|
||||
/* Typography */
|
||||
--font-family-sans: 'Noto Sans CJK TC', 'Inter', system-ui, -apple-system, sans-serif;
|
||||
--font-family-heading: 'Noto Sans CJK TC', 'Inter', system-ui, -apple-system, sans-serif;
|
||||
|
||||
/* Spacing */
|
||||
--spacing-xs: 0.25rem;
|
||||
--spacing-sm: 0.5rem;
|
||||
--spacing-md: 1rem;
|
||||
--spacing-lg: 1.5rem;
|
||||
--spacing-xl: 2rem;
|
||||
--spacing-2xl: 3rem;
|
||||
|
||||
/* Border Radius */
|
||||
--radius-sm: 0.25rem;
|
||||
--radius-md: 0.5rem;
|
||||
--radius-lg: 0.75rem;
|
||||
--radius-xl: 1rem;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||
|
||||
/* Transitions */
|
||||
--transition-fast: 150ms ease-in-out;
|
||||
--transition-normal: 250ms ease-in-out;
|
||||
--transition-slow: 350ms ease-in-out;
|
||||
}
|
||||
|
||||
/* Dark Theme (if needed in future) */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--color-background: #1A202C;
|
||||
--color-surface: #2D3748;
|
||||
--color-text: #F7FAFC;
|
||||
--color-text-muted: #A0AEC0;
|
||||
--color-border: #4A5568;
|
||||
}
|
||||
}
|
||||
|
||||
/* Base Styles */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: var(--font-family-sans);
|
||||
line-height: 1.6;
|
||||
color: var(--color-text);
|
||||
background-color: var(--color-background);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: inherit;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
/* Typography Classes */
|
||||
.text-gradient {
|
||||
background: linear-gradient(135deg, var(--color-primary), var(--color-accent));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
/* Animation Classes */
|
||||
.fade-in {
|
||||
animation: fadeIn var(--transition-normal) ease-in-out;
|
||||
}
|
||||
|
||||
.slide-up {
|
||||
animation: slideUp var(--transition-normal) ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(1rem);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Utility Classes */
|
||||
.glass-effect {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.shadow-custom {
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
/* Component Specific Styles */
|
||||
.nav-link {
|
||||
position: relative;
|
||||
transition: color var(--transition-fast);
|
||||
}
|
||||
|
||||
.nav-link::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -2px;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
background: var(--color-primary);
|
||||
transition: width var(--transition-fast);
|
||||
}
|
||||
|
||||
.nav-link:hover::after {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Active Navigation Link Indicator */
|
||||
.nav-active {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -2px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 70%;
|
||||
height: 2px;
|
||||
background: var(--color-secondary);
|
||||
}
|
||||
|
||||
/* Prose/Markdown Styles */
|
||||
.prose-custom {
|
||||
color: var(--color-text);
|
||||
font-family: var(--font-family-sans);
|
||||
}
|
||||
|
||||
.prose-custom h1,
|
||||
.prose-custom h2,
|
||||
.prose-custom h3,
|
||||
.prose-custom h4,
|
||||
.prose-custom h5,
|
||||
.prose-custom h6 {
|
||||
color: var(--color-text);
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
margin-top: var(--spacing-xl);
|
||||
margin-bottom: var(--spacing-md);
|
||||
}
|
||||
|
||||
.prose-custom h1 {
|
||||
font-size: 2.25rem;
|
||||
}
|
||||
|
||||
.prose-custom h2 {
|
||||
font-size: 1.875rem;
|
||||
}
|
||||
|
||||
.prose-custom h3 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.prose-custom p {
|
||||
margin-bottom: var(--spacing-md);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.prose-custom a {
|
||||
color: var(--color-primary);
|
||||
text-decoration: none;
|
||||
transition: color var(--transition-fast);
|
||||
}
|
||||
|
||||
.prose-custom a:hover {
|
||||
color: #1a2f7a;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.prose-custom strong {
|
||||
color: var(--color-text);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.prose-custom em {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.prose-custom ul,
|
||||
.prose-custom ol {
|
||||
margin-bottom: var(--spacing-md);
|
||||
padding-left: var(--spacing-lg);
|
||||
}
|
||||
|
||||
.prose-custom li {
|
||||
margin-bottom: var(--spacing-xs);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.prose-custom blockquote {
|
||||
border-left: 4px solid var(--color-primary);
|
||||
padding-left: var(--spacing-md);
|
||||
margin: var(--spacing-lg) 0;
|
||||
color: var(--color-text-muted);
|
||||
font-style: italic;
|
||||
background: var(--color-surface);
|
||||
padding: var(--spacing-md);
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
|
||||
.prose-custom code {
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text);
|
||||
padding: 0.125rem 0.25rem;
|
||||
border-radius: var(--radius-sm);
|
||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
.prose-custom pre {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--spacing-md);
|
||||
overflow-x: auto;
|
||||
margin: var(--spacing-lg) 0;
|
||||
}
|
||||
|
||||
.prose-custom pre code {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.prose-custom hr {
|
||||
border: 0;
|
||||
border-top: 1px solid var(--color-border);
|
||||
margin: var(--spacing-2xl) 0;
|
||||
}
|
||||
|
||||
.prose-custom table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: var(--spacing-lg) 0;
|
||||
}
|
||||
|
||||
.prose-custom th,
|
||||
.prose-custom td {
|
||||
border: 1px solid var(--color-border);
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.prose-custom th {
|
||||
background: var(--color-surface);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.prose-custom img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
border-radius: var(--radius-md);
|
||||
margin: var(--spacing-md) 0;
|
||||
}
|
||||
|
||||
/* Button Styles */
|
||||
.btn-primary {
|
||||
background: var(--color-primary);
|
||||
color: white;
|
||||
padding: var(--spacing-sm) var(--spacing-lg);
|
||||
border-radius: var(--radius-md);
|
||||
border: none;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-fast);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #1a2f7a;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--color-secondary);
|
||||
color: white;
|
||||
padding: var(--spacing-sm) var(--spacing-lg);
|
||||
border-radius: var(--radius-md);
|
||||
border: none;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-fast);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: #e08e0b;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
const sharedConfig = require('@enchun/shared/tailwind-config');
|
||||
import sharedConfig from '@enchun/shared/tailwind-config'
|
||||
|
||||
module.exports = {
|
||||
const config = {
|
||||
...sharedConfig,
|
||||
content: [
|
||||
'./src/**/*.{astro,tsx,ts,jsx,js,mdx}',
|
||||
...sharedConfig.content
|
||||
]
|
||||
};
|
||||
|
||||
export default config;
|
||||
23
apps/frontend/tests/auth.spec.ts
Normal file
23
apps/frontend/tests/auth.spec.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { authService } from '../src/services/auth';
|
||||
|
||||
describe('Auth Service', () => {
|
||||
it('should login user', async () => {
|
||||
// Mock fetch
|
||||
global.fetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ user: { id: 1, email: 'test@example.com' }, token: 'token' })
|
||||
})
|
||||
);
|
||||
|
||||
const result = await authService.login('test@example.com', 'password');
|
||||
expect(result.user.email).toBe('test@example.com');
|
||||
});
|
||||
|
||||
it('should get current user', async () => {
|
||||
authService.token = 'token';
|
||||
const user = await authService.getCurrentUser();
|
||||
expect(user).toBeDefined();
|
||||
});
|
||||
});
|
||||
10
apps/frontend/tests/components.spec.ts
Normal file
10
apps/frontend/tests/components.spec.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { render } from '@testing-library/react'; // Assume setup
|
||||
|
||||
describe('Header Component', () => {
|
||||
it('renders navigation links', () => {
|
||||
// const { getByText } = render(<Header />);
|
||||
// expect(getByText('關於恩群')).toBeInTheDocument();
|
||||
expect(true).toBe(true); // Placeholder
|
||||
});
|
||||
});
|
||||
19
apps/frontend/tests/contact.spec.ts
Normal file
19
apps/frontend/tests/contact.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('contact form submission', async ({ page }) => {
|
||||
await page.goto('/contact-us');
|
||||
|
||||
await page.fill('#name', 'Test User');
|
||||
await page.fill('#email', 'test@example.com');
|
||||
await page.fill('#message', 'Test message');
|
||||
|
||||
// Mock form submission
|
||||
await page.route('**/submit-contact', async route => {
|
||||
await route.fulfill({ status: 200, body: 'OK' });
|
||||
});
|
||||
|
||||
await page.click('button[type="submit"]');
|
||||
|
||||
// Check for success message or redirect
|
||||
await expect(page.locator('body')).toContainText('submitted');
|
||||
});
|
||||
9
apps/frontend/wrangler.toml
Normal file
9
apps/frontend/wrangler.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
name = "enchun-frontend"
|
||||
compatibility_date = "2024-01-01"
|
||||
pages_build_output_dir = "dist"
|
||||
|
||||
[vars]
|
||||
PAYLOAD_CMS_URL = "https://enchun-admin.anlstudio.cc"
|
||||
|
||||
[env.production.vars]
|
||||
PAYLOAD_CMS_URL = "https://enchun-admin.anlstudio.cc"
|
||||
72
astro-routing-mapping.md
Normal file
72
astro-routing-mapping.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# Astro Routing Mapping
|
||||
|
||||
This document specifies the mapping from downloaded HTML files in `research/www.enchun.tw/` to Astro routing files in `frontend/src/pages/`. The purpose is to recreate the Astro pages by converting the HTML content into Astro components.
|
||||
|
||||
## Static Routes
|
||||
|
||||
| Route | Astro File | Source HTML |
|
||||
|-------|------------|-------------|
|
||||
| `/` | `src/pages/index.astro` | `research/www.enchun.tw/index.html` |
|
||||
| `/about-enchun` | `src/pages/about-enchun.astro` | `research/www.enchun.tw/about-enchun.html` |
|
||||
| `/contact-us` | `src/pages/contact-us.astro` | `research/www.enchun.tw/contact-us.html` |
|
||||
| `/marketing-solutions` | `src/pages/marketing-solutions.astro` | `research/www.enchun.tw/marketing-solutions.html` |
|
||||
| `/news` | `src/pages/news.astro` | `research/www.enchun.tw/news.html` |
|
||||
| `/website-portfolio` | `src/pages/website-portfolio.astro` | `research/www.enchun.tw/website-portfolio.html` |
|
||||
| `/teams` | `src/pages/teams.astro` | `research/www.enchun.tw/teams.html` |
|
||||
|
||||
## Dynamic Routes
|
||||
|
||||
### Blog Posts (`/xing-xiao-fang-da-jing/[slug]`)
|
||||
|
||||
- Astro File: `src/pages/xing-xiao-fang-da-jing/[slug].astro`
|
||||
- Source Folder: `research/www.enchun.tw/xing-xiao-fang-da-jing/`
|
||||
- Description: Dynamic individual blog post pages. Posts are managed in Payload CMS and can be added/removed.
|
||||
- Implementation: Use Astro's `getStaticPaths` to fetch post slugs dynamically from Payload CMS API.
|
||||
- Files: Existing `.html` files for initial migration; future paths generated from CMS.
|
||||
|
||||
### Blog Categories (`/wen-zhang-fen-lei/[slug]`)
|
||||
|
||||
- Astro File: `src/pages/wen-zhang-fen-lei/[slug].astro`
|
||||
- Source Folder: `research/www.enchun.tw/wen-zhang-fen-lei/`
|
||||
- Description: Dynamic category listing pages for blog posts. Categories are managed in Payload CMS and can be added/removed dynamically.
|
||||
- Current categories in Payload CMS (subject to change):
|
||||
- 恩群數位最新公告 (slug: en-qun-shu-wei-zui-xin-gong-gao)
|
||||
- 行銷時事最前線 (slug: xing-xiao-shi-shi-zui-qian-xian)
|
||||
- Meta小學堂 (slug: meta-xiao-xue-tang)
|
||||
- Google小學堂 (slug: google-xiao-xue-tang)
|
||||
- Implementation: Use Astro's `getStaticPaths` to fetch category slugs dynamically from Payload CMS API.
|
||||
- Files: Existing `.html` files for initial migration; future paths generated from CMS.
|
||||
|
||||
### Portfolio Projects (`/webdesign-profolio/[slug]`)
|
||||
|
||||
- Astro File: `src/pages/webdesign-profolio/[slug].astro`
|
||||
- Source Folder: Not directly available; portfolio items are managed in Payload CMS.
|
||||
- Description: Dynamic individual portfolio project pages. Projects are managed in Payload CMS and can be added/removed.
|
||||
- Implementation: Use Astro's `getStaticPaths` to fetch project slugs dynamically from Payload CMS API.
|
||||
- Example mappings: `web-design-project-2` → `/webdesign-profolio/web-design-project-2` (based on current sitemap)
|
||||
|
||||
## Conversion Process
|
||||
|
||||
1. For static routes: Convert HTML files directly to Astro pages by extracting content, converting styles to Tailwind, and breaking into components.
|
||||
2. For dynamic routes: Create Astro files with `getStaticPaths` to fetch slugs from Payload CMS API. For initial migration, use existing HTML files as placeholders; replace with CMS data integration.
|
||||
3. Ensure SEO meta tags are preserved or dynamically set from CMS fields.
|
||||
4. Categories and content are editable in Payload CMS, so routes will be generated dynamically post-migration.
|
||||
|
||||
## Blog Post Structure (from DevTools Inspection)
|
||||
|
||||
Based on inspecting a sample post (e.g., `/xing-xiao-fang-da-jing/2-zhao-yao-kong-xiao-fei-zhe-de-xin`):
|
||||
|
||||
- **Header/Navigation**: Top nav with links to main sections; includes "回到文章列表" (back to list) link.
|
||||
- **Title**: `<h1>` and `<h2>` with post title.
|
||||
- **Publish Date**: "文章發布日期:" + date (e.g., "January 20, 2022").
|
||||
- **Content**: Text paragraphs separated by `<br>` tags; no images or rich media in sample.
|
||||
- **Footer**: Company info, contact details, links to services and categories.
|
||||
|
||||
Map to Payload CMS: title, publish_date, content (rich text), category.
|
||||
|
||||
## Notes
|
||||
|
||||
- All HTML files are in Chinese; ensure proper encoding and localization if needed.
|
||||
- Images and assets referenced in HTML may need to be downloaded and placed in `frontend/public/`.
|
||||
- Scripts and external dependencies should be migrated to Astro's script handling.
|
||||
- For dynamic routes, implement `getStaticPaths` to pull slugs from CMS; use existing HTML for initial static generation.
|
||||
42
backend/scripts/migrate.js
Normal file
42
backend/scripts/migrate.js
Normal file
@@ -0,0 +1,42 @@
|
||||
// Migration script to import content from CSVs to Payload CMS
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const csv = require('csv-parser'); // Assume installed
|
||||
const { Payload } = require('payload');
|
||||
|
||||
async function migrate() {
|
||||
// Initialize Payload
|
||||
const payload = new Payload({
|
||||
// Config
|
||||
});
|
||||
|
||||
// Read CSV files
|
||||
const csvFiles = [
|
||||
'research/恩群數位行銷 - 文章分類s.csv',
|
||||
'research/恩群數位行銷 - 行銷放大鏡集.csv',
|
||||
'research/恩群數位行銷 - 網站設計範本s.csv'
|
||||
];
|
||||
|
||||
for (const file of csvFiles) {
|
||||
const data = [];
|
||||
fs.createReadStream(path.join(__dirname, '../../', file))
|
||||
.pipe(csv())
|
||||
.on('data', (row) => data.push(row))
|
||||
.on('end', async () => {
|
||||
// Import to Payload collections
|
||||
for (const item of data) {
|
||||
try {
|
||||
await payload.create({
|
||||
collection: 'posts', // or appropriate collection
|
||||
data: item
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Migration error:', error);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
migrate().catch(console.error);
|
||||
142
combined-prd-plan.md
Normal file
142
combined-prd-plan.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# Combined Document: PRD and Astro Migration Plan
|
||||
|
||||
### **Product Requirements Document: `enchun.tw` Website Migration to Astro (v2)**
|
||||
|
||||
**1. Introduction**
|
||||
|
||||
This document outlines the requirements for migrating the existing `enchun.tw` website to a new, modern web application built with the Astro framework and managed by Payload CMS. The primary goal is to create a faster, more secure, and more maintainable website, complete with a secure authentication system and a user-friendly editing experience for copywriters. The project will preserve all existing content, functionality, and SEO value while implementing a more logical site structure.
|
||||
|
||||
**2. Goals & Objectives**
|
||||
|
||||
* **Performance:** Achieve Lighthouse scores of 95+ on public-facing pages.
|
||||
* **Maintainability:** Provide a user-friendly, web-based interface for content editors via Payload CMS, protected by a robust authentication system.
|
||||
* **Developer Experience:** Leverage Astro's modern features for a fast frontend build process and easier component management.
|
||||
* **Security:** Implement role-based access control (RBAC) to secure the CMS and dashboard areas.
|
||||
* **Future-Proofing:** Build on a modern, flexible stack that can easily integrate with other services and APIs.
|
||||
|
||||
**3. Target Audience**
|
||||
|
||||
* **Public Users:** Potential and existing clients, industry peers.
|
||||
* **Authenticated Users:**
|
||||
* **Content Editors/Copywriters:** Internal team members who will manage website content.
|
||||
* **Administrators:** Technical staff responsible for managing users and site settings.
|
||||
|
||||
**4. Functional Requirements**
|
||||
|
||||
**4.1. Redesigned Page Structure & Routing**
|
||||
|
||||
The application will feature a clear separation between public and protected routes.
|
||||
|
||||
* **Public Routes:**
|
||||
* `/` (Homepage)
|
||||
* `/about-enchun`
|
||||
* `/contact-us`
|
||||
* `/marketing-solutions`
|
||||
* `/news` (Blog listing page)
|
||||
* `/teams`
|
||||
* `/website-portfolio` (Portfolio listing page)
|
||||
|
||||
* **Dynamic Routes:**
|
||||
* `/xing-xiao-fang-da-jing/[slug]` (Individual blog posts)
|
||||
* `/wen-zhang-fen-lei/[slug]` (Blog category pages)
|
||||
* `/webdesign-profolio/[slug]` (Individual portfolio projects)
|
||||
|
||||
* **Protected Routes (Require Authentication):**
|
||||
* `/admin/login` (Login page)
|
||||
* `/admin/dashboard` (A general dashboard for authenticated users)
|
||||
* `/admin/cms` (The embedded Payload CMS admin interface)
|
||||
|
||||
**4.2. Authentication & Authorization**
|
||||
|
||||
* **Authentication Provider:** The site will use Payload CMS default authentication method.
|
||||
* **Login:** The frontend Astro does not have a login button; use a subdomain to connect to Payload CMS.
|
||||
* **Access Control:** All routes under `/admin/*` will be protected. Unauthenticated users attempting to access these routes will be redirected to the login page.
|
||||
* **Role-Based Access Control (RBAC):**
|
||||
* **Administrator (`admin`):** Full access to the Payload CMS, including content creation/editing, user management, and system settings.
|
||||
* **Editor (`editor`):** Can create, edit, and manage content (blog posts, portfolio items) but cannot access system settings or manage users.
|
||||
* The CMS and dashboard will restrict visibility and actions based on the logged-in user's role.
|
||||
|
||||
**4.3. Key Features**
|
||||
|
||||
* **Content Management:** All public content will be managed via a self-hosted Payload CMS instance. The CMS admin panel will be accessible only to authenticated users at `/admin/cms`.
|
||||
* **Contact Form:** The public `/contact` page will feature a functional contact form. Submissions will be handled securely by a Cloudflare Worker.
|
||||
* **SEO:**
|
||||
* A dynamic `sitemap.xml` will be automatically generated.
|
||||
* Payload CMS will include dedicated SEO fields (meta title, description, Open Graph tags) for all pages and collections.
|
||||
* **Redirects:** A 301 redirect map will be implemented to permanently redirect all old URLs from `enchun-sitemap.md` to their new, redesigned equivalents to preserve SEO equity.
|
||||
|
||||
**5. Non-Functional Requirements**
|
||||
|
||||
* **Styling:** The project will use **Tailwind CSS**.
|
||||
* **Accessibility:** The site must adhere to WCAG 2.1 AA standards.
|
||||
* **Deployment:** The Astro frontend will be deployed on **Cloudflare Pages** in SSR (Server-Side Rendering) mode to support the authentication layer. The Payload CMS backend will run on self-hosted Coolify platform, and serverless functions will run on **Cloudflare Workers**.
|
||||
* **Workspace Layout:** Monorepo managed with **pnpm** workspaces. Packages include `frontend/` (Astro), `backend/` (Payload CMS), and `packages/shared/` for cross-cutting TypeScript utilities.
|
||||
|
||||
**6. Technology Stack**
|
||||
|
||||
* **Framework:** Astro (in SSR mode)
|
||||
* **Authentication:** Payload CMS default authentication
|
||||
* **UI Components:** Astro components
|
||||
* **Styling:** Tailwind CSS
|
||||
* **CMS:** Payload CMS is deploy on self-hosted coolify platform
|
||||
* **Deployment:** Cloudflare Pages & Cloudflare Workers
|
||||
|
||||
**7. Migration Plan (High-Level)**
|
||||
|
||||
1. **Phase 1: Project Setup**
|
||||
* Initialize a pnpm workspace monorepo with `frontend/`, `backend/`, and `packages/shared/`.
|
||||
* Initialize a new Astro project configured for SSR inside `frontend/`.
|
||||
* Set up Payload CMS for self-hosted Coolify platform inside `backend/`.
|
||||
* Configure Tailwind CSS and shared TypeScript utilities in `packages/shared/`.
|
||||
2. **Phase 2: Authentication & CMS Setup**
|
||||
* Integrate Payload CMS authentication and configure the login flow.
|
||||
* Define the collections and user roles (`admin`, `editor`) within Payload.
|
||||
3. **Phase 3: Content Migration**
|
||||
* Write a script to import content from the CSV files into the Payload CMS via its API.
|
||||
4. **Phase 4: Page & Template Implementation**
|
||||
* Build all public pages and templates, fetching data from the Payload API.
|
||||
* Build the protected `/admin` area, including the dashboard and the embedded CMS panel.
|
||||
5. **Phase 5: Functionality & SEO**
|
||||
* Implement the contact form with its Cloudflare Worker backend.
|
||||
* Implement the 301 redirect map and all other SEO requirements.
|
||||
6. **Phase 6: Testing & Deployment**
|
||||
* Thoroughly test all public pages, protected routes, user roles, and functionality.
|
||||
* Deploy the Astro frontend to Cloudflare Pages, and the Payload CMS backend to Coolify.
|
||||
* Configure DNS and go live.
|
||||
|
||||
**8. Out of Scope**
|
||||
|
||||
* Frontend user accounts or public-facing login capabilities.
|
||||
* A complete visual redesign. The project aims to migrate the existing design to the new framework.
|
||||
|
||||
## Astro Migration Plan
|
||||
|
||||
## Phase 1 – Discovery & Gap Analysis
|
||||
- Inventory `research/www.enchun.tw/` HTML assets and map them against `route-structure.md` to verify required routes.
|
||||
- Capture shared partials (headers, footers, CTA blocks) and cross-page assets (images, fonts, scripts).
|
||||
- Note gaps between scraped content and Payload CMS scope to prevent out-of-scope feature work.
|
||||
|
||||
## Phase 2 – Astro Foundation
|
||||
- Confirm Astro project root (`frontend/` vs `apps/frontend/`) and align `pnpm` workspace filters.
|
||||
- Configure TypeScript support, Tailwind/global styles, and a base `src/layouts/Layout.astro` that centralizes `<head>`, navigation, and footer markup.
|
||||
- Migrate critical global CSS from `enchun.webflow.shared*.css`, pruning unused rules to keep the baseline lean.
|
||||
|
||||
## Phase 3 – Component Extraction
|
||||
- Break repeated HTML fragments (hero modules, feature grids, testimonial sliders, footer columns) into focused components under `src/components/`.
|
||||
- Expose component props for dynamic content (titles, copy, imagery) to support later CMS integration.
|
||||
- Scope styles with component-level CSS modules or Tailwind utilities to avoid collisions and honor DRY.
|
||||
|
||||
## Phase 4 – Route Implementation
|
||||
- Translate each static page (`index`, `about-enchun`, `marketing-solutions`, `teams`, `contact-us`, `news`, `website-portfolio`) into `.astro` files inside `src/pages/`, preserving current URL structure.
|
||||
- Stand up dynamic routes (`xing-xiao-fang-da-jing/[slug].astro`, `wen-zhang-fen-lei/[slug].astro`, `webdesign-profolio/[slug].astro`) with loaders that read corresponding HTML files until Payload integration lands.
|
||||
- Add fallbacks for missing slugs (404 handling) to preserve production stability.
|
||||
|
||||
## Phase 5 – Data & CMS Integration
|
||||
- Implement `src/services/payload.ts` helpers that wrap Payload REST/GraphQL endpoints, returning typed data models.
|
||||
- Wire page frontmatter or Astro `getStaticPaths`/`getStaticProps` to these helpers for dynamic collections.
|
||||
- Keep CMS-specific logic isolated so components remain presentational and adhere to SOLID.
|
||||
|
||||
## Phase 6 – QA & Deployment
|
||||
- Add smoke coverage with Vitest for critical components and Playwright flows for forms/navigation if time permits.
|
||||
- Configure Cloudflare Pages build: command `pnpm --filter frontend build`, output directory `frontend/dist` (adjust if project root differs).
|
||||
- Validate sitemap, robots, and redirects before launch; document required environment variables (`PAYLOAD_CMS_URL`, `PAYLOAD_CMS_API_KEY`) for Cloudflare.
|
||||
@@ -4,6 +4,7 @@
|
||||
"packageManager": "pnpm@10.17.0",
|
||||
"scripts": {
|
||||
"dev": "turbo run dev --parallel",
|
||||
"dev:stop": "echo 'Stopping dev servers...' && pkill -f 'astro.js dev' && pkill -f 'next dev' && pkill -f 'pnpm dev' && echo 'Dev servers stopped' || echo 'No dev servers were running'",
|
||||
"build": "turbo run build",
|
||||
"lint": "turbo run lint",
|
||||
"test": "turbo run test"
|
||||
|
||||
@@ -2,12 +2,16 @@
|
||||
"name": "@enchun/shared",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
"./tailwind-config": {
|
||||
"default": "./tailwind.config.cjs"
|
||||
"default": "./tailwind.config.js"
|
||||
},
|
||||
"./tailwind-config-v3": {
|
||||
"default": "./tailwind.config.v3.js"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"tailwindcss": "^3.4.0"
|
||||
"tailwindcss": "^4.1.14"
|
||||
}
|
||||
}
|
||||
|
||||
88
packages/shared/tailwind.config.js
Normal file
88
packages/shared/tailwind.config.js
Normal file
@@ -0,0 +1,88 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: [
|
||||
'../../apps/frontend/src/**/*.{astro,tsx,ts,jsx,js,mdx}',
|
||||
'../../apps/backend/src/**/*.{tsx,ts,jsx,js}'
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#1F3A93',
|
||||
secondary: '#F39C12',
|
||||
accent: '#16A085',
|
||||
background: '#FFFFFF',
|
||||
surface: '#F7FAFC',
|
||||
text: '#1A202C'
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Noto Sans CJK TC', 'Inter', 'system-ui', '-apple-system', 'sans-serif'],
|
||||
heading: ['Noto Sans CJK TC', 'Inter', 'system-ui', '-apple-system', 'sans-serif'],
|
||||
},
|
||||
typography: {
|
||||
DEFAULT: {
|
||||
css: {
|
||||
fontFamily: 'Noto Sans CJK TC, Inter, system-ui, -apple-system, sans-serif',
|
||||
color: 'var(--color-text)',
|
||||
a: {
|
||||
color: 'var(--color-primary)',
|
||||
'&:hover': {
|
||||
color: '#1a2f7a',
|
||||
},
|
||||
},
|
||||
h1: {
|
||||
color: 'var(--color-text)',
|
||||
},
|
||||
h2: {
|
||||
color: 'var(--color-text)',
|
||||
},
|
||||
h3: {
|
||||
color: 'var(--color-text)',
|
||||
},
|
||||
h4: {
|
||||
color: 'var(--color-text)',
|
||||
},
|
||||
strong: {
|
||||
color: 'var(--color-text)',
|
||||
},
|
||||
code: {
|
||||
color: 'var(--color-text)',
|
||||
backgroundColor: 'var(--color-surface)',
|
||||
borderRadius: 'var(--radius-sm)',
|
||||
padding: '0.125rem 0.25rem',
|
||||
},
|
||||
'code::before': {
|
||||
content: '""',
|
||||
},
|
||||
'code::after': {
|
||||
content: '""',
|
||||
},
|
||||
pre: {
|
||||
backgroundColor: 'var(--color-surface)',
|
||||
borderRadius: 'var(--radius-md)',
|
||||
border: '1px solid var(--color-border)',
|
||||
},
|
||||
blockquote: {
|
||||
borderLeftColor: 'var(--color-primary)',
|
||||
color: 'var(--color-text-muted)',
|
||||
},
|
||||
hr: {
|
||||
borderColor: 'var(--color-border)',
|
||||
},
|
||||
ul: {
|
||||
color: 'var(--color-text)',
|
||||
},
|
||||
ol: {
|
||||
color: 'var(--color-text)',
|
||||
},
|
||||
li: {
|
||||
color: 'var(--color-text)',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
require('@tailwindcss/typography'),
|
||||
]
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
export default {
|
||||
content: [
|
||||
'../../frontend/src/**/*.{astro,tsx,ts,jsx,js,mdx}'
|
||||
'../../apps/backend/src/**/*.{tsx,ts,jsx,js}'
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
@@ -16,4 +16,4 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
plugins: []
|
||||
};
|
||||
};
|
||||
2172
pnpm-lock.yaml
generated
2172
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
13
research/www.enchun.tw/_downloads.html
Normal file
13
research/www.enchun.tw/_downloads.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title> Downloads </title>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Downloads </h1>
|
||||
<ul>
|
||||
<li><a id="https://www.enchun.tw/" href="index.html"> 恩群數位行銷 </a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
32
research/www.enchun.tw/about-enchun.html
Normal file
32
research/www.enchun.tw/about-enchun.html
Normal file
File diff suppressed because one or more lines are too long
32
research/www.enchun.tw/contact-us.html
Normal file
32
research/www.enchun.tw/contact-us.html
Normal file
File diff suppressed because one or more lines are too long
53
research/www.enchun.tw/index.html
Normal file
53
research/www.enchun.tw/index.html
Normal file
File diff suppressed because one or more lines are too long
32
research/www.enchun.tw/marketing-solutions.html
Normal file
32
research/www.enchun.tw/marketing-solutions.html
Normal file
File diff suppressed because one or more lines are too long
34
research/www.enchun.tw/news.html
Normal file
34
research/www.enchun.tw/news.html
Normal file
File diff suppressed because one or more lines are too long
1
research/www.enchun.tw/robots.ssl.txt
Normal file
1
research/www.enchun.tw/robots.ssl.txt
Normal file
@@ -0,0 +1 @@
|
||||
Sitemap: https://www.enchun.tw/sitemap.xml
|
||||
32
research/www.enchun.tw/teams.html
Normal file
32
research/www.enchun.tw/teams.html
Normal file
File diff suppressed because one or more lines are too long
32
research/www.enchun.tw/website-portfolio.html
Normal file
32
research/www.enchun.tw/website-portfolio.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user