mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-10 23:15:40 +00:00
bde15d45ca
* Rename "Phases" to "Plans" and clean up deprecated phase aliases
Renames the default "Phases" collection to "Plans" across the full stack:
- DB migration renames existing collections in-place (name, slug, prefix PLAN, icon 🗺️)
- Removes all deprecated Phase* backward-compat aliases from models and store
- Removes --phase CLI flag (use --parent instead)
- Updates convention triggers: on-phase-start/complete → on-plan-start/complete
- Updates dashboard API: active_phases → active_plans, /phases-progress → /plans-progress
- Updates all frontend components, types, and documentation
Closes IDEA-124
* Fix CSRF cookie not being cleared on logout
The SessionAuth middleware was re-issuing a CSRF cookie before the
logout handler could clear it, resulting in two Set-Cookie headers.
Skip CSRF re-issue for /api/v1/auth/ paths since auth endpoints
manage their own CSRF cookies (login sets, logout clears).
* Fix migration issues found in Codex review
- P1: Move doc_type UPDATE from migration 024 into 025, which recreates
the table with the new CHECK constraint first (SQLite enforces CHECK
on UPDATE, so the old constraint would reject 'plan')
- P1: Add PostgreSQL migration 005 for the collection rename (phases →
plans) — previously only existed on the SQLite path
- P2: Recreate FTS triggers, indexes, and rebuild FTS after the table
swap in migration 025 (DROP TABLE drops associated objects in SQLite)
* Fix parent filter field name and sync .agents skill copy
Codex review round 2 findings:
- P1: Parent filter compared against `parent_id` (wrong) instead of
`parent_link_id` — plan filtering in collection view was broken
- P1: .agents/skills/pad/SKILL.md still had old --phase flags and
"Phases" references — synced from the updated .claude copy
- P2: Accept legacy 'phase' filter key for backward compat with
existing saved views that serialized the old key name
* Fix PG migration JSONB casting and add slug collision guards
Codex PR review bot findings:
- P1: PostgreSQL REPLACE/LIKE don't work on JSONB columns — cast
schema::text and fields::text before string ops, then back to ::jsonb
- P1: If a workspace already has a custom 'plans' collection, the
rename hits UNIQUE(workspace_id, slug) — added NOT EXISTS guard
to both SQLite and PostgreSQL migrations
363 lines
6.1 KiB
Go
363 lines
6.1 KiB
Go
package models
|
|
|
|
import "time"
|
|
|
|
type Template struct {
|
|
Type string `json:"type"`
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
Icon string `json:"icon"`
|
|
Content string `json:"content,omitempty"`
|
|
}
|
|
|
|
var Templates = []Template{
|
|
{
|
|
Type: "roadmap",
|
|
Name: "Roadmap",
|
|
Description: "High-level project scope, goals, and phased plan",
|
|
Icon: "\U0001F4CB",
|
|
Content: `# {Title}
|
|
|
|
## Vision
|
|
|
|
What are we building and why?
|
|
|
|
## Goals
|
|
|
|
- [ ] Goal 1
|
|
- [ ] Goal 2
|
|
- [ ] Goal 3
|
|
|
|
## Phases
|
|
|
|
### Phase 1: {Name}
|
|
|
|
**Status:** Not Started
|
|
**Target:** {Timeframe}
|
|
|
|
Summary of what this phase covers.
|
|
|
|
### Phase 2: {Name}
|
|
|
|
**Status:** Not Started
|
|
**Target:** {Timeframe}
|
|
|
|
Summary of what this phase covers.
|
|
|
|
### Phase 3: {Name}
|
|
|
|
**Status:** Not Started
|
|
**Target:** {Timeframe}
|
|
|
|
Summary of what this phase covers.
|
|
|
|
## Success Criteria
|
|
|
|
How do we know when we're done?
|
|
|
|
- [ ] Criterion 1
|
|
- [ ] Criterion 2
|
|
- [ ] Criterion 3
|
|
|
|
## Open Questions
|
|
|
|
- Question 1
|
|
- Question 2
|
|
`,
|
|
},
|
|
{
|
|
Type: "plan",
|
|
Name: "Plan",
|
|
Description: "Scoped implementation plan for a specific milestone",
|
|
Icon: "\U0001F3D7\uFE0F",
|
|
Content: `# {Title}
|
|
|
|
## Overview
|
|
|
|
What does this plan accomplish? What's the scope?
|
|
|
|
## Prerequisites
|
|
|
|
What needs to be done before this plan can start?
|
|
|
|
- [ ] Prerequisite 1
|
|
- [ ] Prerequisite 2
|
|
|
|
## Tasks
|
|
|
|
- [ ] Task 1
|
|
- [ ] Task 2
|
|
- [ ] Task 3
|
|
- [ ] Task 4
|
|
- [ ] Task 5
|
|
|
|
## Technical Details
|
|
|
|
Implementation specifics, patterns, libraries, key decisions.
|
|
|
|
## Edge Cases & Risks
|
|
|
|
- **Risk:** Description and mitigation
|
|
- **Edge case:** Description and handling
|
|
|
|
## Definition of Done
|
|
|
|
- [ ] Criteria 1
|
|
- [ ] Criteria 2
|
|
- [ ] Criteria 3
|
|
|
|
## Notes
|
|
|
|
Additional context, links, or observations.
|
|
`,
|
|
},
|
|
{
|
|
Type: "architecture",
|
|
Name: "Architecture",
|
|
Description: "System design, data models, and technical decisions",
|
|
Icon: "\U0001F9E0",
|
|
Content: `# {Title}
|
|
|
|
## Overview
|
|
|
|
High-level description of this architectural component or decision.
|
|
|
|
## Context
|
|
|
|
Why does this exist? What problem does it solve? What constraints are we working within?
|
|
|
|
## Design
|
|
|
|
### Data Model
|
|
|
|
Describe the core data structures.
|
|
|
|
### API / Interface
|
|
|
|
How do other components interact with this?
|
|
|
|
### Flow
|
|
|
|
Step-by-step flow for the primary use case.
|
|
|
|
## Decisions
|
|
|
|
| Decision | Choice | Rationale |
|
|
|----------|--------|-----------|
|
|
| | | |
|
|
|
|
## Trade-offs
|
|
|
|
What did we choose NOT to do, and why?
|
|
|
|
## Dependencies
|
|
|
|
What does this depend on? What depends on this?
|
|
|
|
## Future Considerations
|
|
|
|
What might change? What are we deferring?
|
|
`,
|
|
},
|
|
{
|
|
Type: "ideation",
|
|
Name: "Ideation",
|
|
Description: "Brainstorms, rough ideas, and explorations",
|
|
Icon: "\U0001F4A1",
|
|
Content: `# {Title}
|
|
|
|
## The Idea
|
|
|
|
What's the core concept? Describe it simply.
|
|
|
|
## Problem
|
|
|
|
What problem does this solve? Who has this problem?
|
|
|
|
## How It Might Work
|
|
|
|
Initial thoughts on implementation or approach.
|
|
|
|
## Questions to Explore
|
|
|
|
- Question 1
|
|
- Question 2
|
|
- Question 3
|
|
|
|
## Pros
|
|
|
|
- Pro 1
|
|
- Pro 2
|
|
|
|
## Cons / Risks
|
|
|
|
- Con 1
|
|
- Con 2
|
|
|
|
## Related
|
|
|
|
Links to related documents, references, or prior art.
|
|
|
|
## Next Steps
|
|
|
|
What would need to happen to move this forward?
|
|
`,
|
|
},
|
|
{
|
|
Type: "feature-spec",
|
|
Name: "Feature Spec",
|
|
Description: "Detailed specification for a specific feature",
|
|
Icon: "\U0001F4C4",
|
|
Content: `# {Title}
|
|
|
|
## Summary
|
|
|
|
One paragraph describing the feature.
|
|
|
|
## Motivation
|
|
|
|
Why build this? What user need does it address?
|
|
|
|
## User Stories
|
|
|
|
- As a [user], I want to [action] so that [benefit]
|
|
- As a [user], I want to [action] so that [benefit]
|
|
|
|
## Detailed Design
|
|
|
|
### Behavior
|
|
|
|
How does the feature work from the user's perspective?
|
|
|
|
### UI / UX
|
|
|
|
Describe the interface.
|
|
|
|
### API Changes
|
|
|
|
New or modified API endpoints.
|
|
|
|
### Data Changes
|
|
|
|
New or modified data structures.
|
|
|
|
## Edge Cases
|
|
|
|
- Edge case 1: How it's handled
|
|
- Edge case 2: How it's handled
|
|
|
|
## Out of Scope
|
|
|
|
What is explicitly NOT part of this feature?
|
|
|
|
## Test Plan
|
|
|
|
- [ ] Test scenario 1
|
|
- [ ] Test scenario 2
|
|
- [ ] Test scenario 3
|
|
|
|
## Open Questions
|
|
|
|
- Question 1
|
|
- Question 2
|
|
`,
|
|
},
|
|
{
|
|
Type: "notes",
|
|
Name: "Notes",
|
|
Description: "General thoughts, meeting notes, or observations",
|
|
Icon: "\U0001F4DD",
|
|
Content: `# {Title}
|
|
|
|
## Notes
|
|
|
|
Start writing here.
|
|
`,
|
|
},
|
|
{
|
|
Type: "prompt-library",
|
|
Name: "Prompt Library",
|
|
Description: "Reusable prompts and agent instructions",
|
|
Icon: "\U0001F4AC",
|
|
Content: `# {Title}
|
|
|
|
## Overview
|
|
|
|
What are these prompts for? When should they be used?
|
|
|
|
## Prompts
|
|
|
|
### {Prompt Name}
|
|
|
|
**Use when:** Description of when to use this prompt.
|
|
|
|
` + "```" + `
|
|
Prompt text goes here.
|
|
` + "```" + `
|
|
|
|
### {Prompt Name}
|
|
|
|
**Use when:** Description of when to use this prompt.
|
|
|
|
` + "```" + `
|
|
Prompt text goes here.
|
|
` + "```" + `
|
|
|
|
## Guidelines
|
|
|
|
Notes on how to use these prompts effectively.
|
|
`,
|
|
},
|
|
{
|
|
Type: "reference",
|
|
Name: "Reference",
|
|
Description: "External information, API docs, or specs for context",
|
|
Icon: "\U0001F4DA",
|
|
Content: `# {Title}
|
|
|
|
## Source
|
|
|
|
Where does this information come from? Include links if applicable.
|
|
|
|
## Content
|
|
|
|
Reference content goes here.
|
|
|
|
## Notes
|
|
|
|
Additional observations or context about this reference material.
|
|
`,
|
|
},
|
|
}
|
|
|
|
func GetTemplate(docType string) *Template {
|
|
for _, t := range Templates {
|
|
if t.Type == docType {
|
|
return &t
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// CustomTemplate is a user-created template stored in the database.
|
|
type CustomTemplate struct {
|
|
ID string `json:"id"`
|
|
WorkspaceID string `json:"workspace_id"`
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
DocType string `json:"doc_type"`
|
|
Icon string `json:"icon"`
|
|
Content string `json:"content,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
type CustomTemplateCreate struct {
|
|
WorkspaceID string `json:"workspace_id"`
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
DocType string `json:"doc_type"`
|
|
Icon string `json:"icon"`
|
|
Content string `json:"content"`
|
|
}
|