ccstart 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -53
- package/bin/create-project.js +6 -9
- package/package.json +2 -2
- package/template/claude/CLAUDE.md +20 -15
- package/template/claude/agents/README.md +4 -7
- package/template/claude/agents/backend.md +231 -76
- package/template/claude/agents/checker.md +76 -51
- package/template/claude/agents/frontend.md +295 -69
- package/template/claude/agents/planner.md +86 -32
- package/template/claude/docs/ROADMAP.md +3 -5
- package/template/claude/docs/agent-orchestration.md +72 -41
- package/template/claude/skills/commit/SKILL.md +97 -0
- package/template/claude/skills/create-pr/SKILL.md +84 -0
- package/template/claude/skills/create-ticket/SKILL.md +102 -0
- package/template/claude/skills/design-feature/SKILL.md +111 -0
- package/template/claude/skills/design-principles/skill.md +237 -0
- package/template/claude/skills/skill-creator/SKILL.md +356 -0
- package/template/.claude/commands/README.md +0 -70
- package/template/.claude/commands/update-claude-md.md +0 -23
- package/template/.claude/hooks/README.md +0 -65
- package/template/.claude/hooks/workflow-detector.sh +0 -61
- package/template/.claude/settings.json.example +0 -18
- package/template/claude/agents/blockchain.md +0 -81
- package/template/claude/agents/coder.md +0 -46
- package/template/claude/agents/researcher.md +0 -56
- package/template/claude/agents/shadcn.md +0 -106
- package/template/claude/plans/README.md +0 -53
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
[](https://www.npmjs.com/package/ccstart)
|
|
7
7
|
|
|
8
|
-
Quick setup for Claude Code projects with built-in agents,
|
|
8
|
+
Quick setup for Claude Code projects with built-in agents, skills, tickets, and orchestration workflows.
|
|
9
9
|
|
|
10
10
|
## Installation
|
|
11
11
|
|
|
@@ -21,40 +21,51 @@ npm install -g ccstart
|
|
|
21
21
|
ccstart my-project
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
## What
|
|
24
|
+
## What You Get
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
```
|
|
27
|
+
my-project/
|
|
28
|
+
├── CLAUDE.md # Project instructions for Claude
|
|
29
|
+
├── claude/
|
|
30
|
+
│ ├── agents/ # 4 specialized agents
|
|
31
|
+
│ ├── docs/ # ROADMAP.md + agent-orchestration.md
|
|
32
|
+
│ ├── skills/ # Workflow automation (commit, create-pr, etc.)
|
|
33
|
+
│ └── tickets/ # Task tracking system
|
|
34
|
+
└── .claude/
|
|
35
|
+
├── agents/ # Agents for Claude Code integration
|
|
36
|
+
└── skills/ # Skills for Claude Code integration
|
|
37
|
+
```
|
|
37
38
|
|
|
38
|
-
##
|
|
39
|
+
## The Workflow
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
- 🔄 **Agent Orchestration Workflows** - Pre-defined workflows that coordinate multiple agents
|
|
42
|
-
- 🔒 **Smart Conflict Resolution** - Handle existing files with skip/rename/overwrite options
|
|
43
|
-
- 📁 **Auto-detects Claude Code** - Creates .claude directory structure automatically
|
|
44
|
-
- 🏃 **Dry Run Mode** - Preview changes before applying them
|
|
45
|
-
- ⚡ **Force Mode** - Skip all prompts for automated workflows
|
|
46
|
-
- 🎭 **Workflow Commands** - Execute complex workflows with single commands
|
|
47
|
-
- 🪝 **Intelligent Hooks** - Automatically detect task patterns and suggest workflows
|
|
41
|
+
### How Claude Uses Your Project
|
|
48
42
|
|
|
49
|
-
|
|
43
|
+
1. **CLAUDE.md** provides context and instructions
|
|
44
|
+
2. **Agents** handle specialized tasks:
|
|
45
|
+
- `planner` - Strategic planning and task breakdown
|
|
46
|
+
- `checker` - Quality assurance and code review
|
|
47
|
+
- `backend` - FastAPI/Python backend development
|
|
48
|
+
- `frontend` - React/TypeScript frontend development
|
|
49
|
+
3. **Skills** automate common workflows:
|
|
50
|
+
- `/commit` - Conventional commits
|
|
51
|
+
- `/create-pr` - Structured pull requests
|
|
52
|
+
- `/create-ticket` - Task ticket creation
|
|
53
|
+
- `/design-feature` - Feature design phases
|
|
54
|
+
4. **Tickets** track tasks with status emojis
|
|
50
55
|
|
|
51
|
-
|
|
52
|
-
npx ccstart my-project
|
|
53
|
-
cd my-project
|
|
56
|
+
### Agent Orchestration Workflows
|
|
54
57
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
Pre-configured workflows that coordinate agents:
|
|
59
|
+
|
|
60
|
+
| Workflow | Flow |
|
|
61
|
+
|----------|------|
|
|
62
|
+
| Feature Development | Planner → Backend/Frontend → Checker |
|
|
63
|
+
| Bug Fix | Planner → Backend/Frontend → Checker |
|
|
64
|
+
| API Development | Planner → Backend → Frontend → Checker |
|
|
65
|
+
| UI Components | Planner → Frontend → Checker |
|
|
66
|
+
| Quality Assurance | Planner → Checker → Fix → Checker |
|
|
67
|
+
|
|
68
|
+
See `claude/docs/agent-orchestration.md` for detailed workflow documentation.
|
|
58
69
|
|
|
59
70
|
## Command Line Options
|
|
60
71
|
|
|
@@ -75,33 +86,24 @@ Examples:
|
|
|
75
86
|
ccstart --agents # Preview available agents
|
|
76
87
|
```
|
|
77
88
|
|
|
78
|
-
##
|
|
79
|
-
|
|
80
|
-
The template includes pre-configured workflows that automatically coordinate agents:
|
|
81
|
-
|
|
82
|
-
- **Feature Development** → Researcher → Planner → Coder → Checker
|
|
83
|
-
- **Bug Fix** → Researcher → Coder → Checker
|
|
84
|
-
- **API Development** → Planner → Backend → Frontend → Checker
|
|
85
|
-
- **Refactoring** → Researcher → Planner → Coder → Checker
|
|
86
|
-
- **UI Components** → Frontend → Shadcn → Checker
|
|
87
|
-
- **Quality Assurance** → Researcher → Checker → Coder → Checker
|
|
88
|
-
|
|
89
|
-
See `claude/docs/agent-orchestration.md` for detailed workflow documentation.
|
|
89
|
+
## Key Features
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
- **Interactive Agent Selection** - Choose which agents to include during setup
|
|
92
|
+
- **Agent Orchestration Workflows** - Pre-defined workflows that coordinate multiple agents
|
|
93
|
+
- **Smart Conflict Resolution** - Handle existing files with skip/rename/overwrite options
|
|
94
|
+
- **Auto-detects Claude Code** - Creates .claude directory structure automatically
|
|
95
|
+
- **Dry Run Mode** - Preview changes before applying them
|
|
96
|
+
- **Force Mode** - Skip all prompts for automated workflows
|
|
92
97
|
|
|
93
|
-
|
|
94
|
-
- `/update-claude-md` - Automatically populate project information in CLAUDE.md
|
|
95
|
-
- `/workflow-*` commands - Execute orchestrated workflows (coming soon)
|
|
98
|
+
## Quick Start
|
|
96
99
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
- Bug reports → suggests `/workflow-bug`
|
|
101
|
-
- API tasks → suggests `/workflow-api`
|
|
102
|
-
- And more! (QA, refactoring, UI components, blockchain)
|
|
100
|
+
```bash
|
|
101
|
+
npx ccstart my-project
|
|
102
|
+
cd my-project
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
# Edit CLAUDE.md with your project details
|
|
105
|
+
# Start using Claude Code with pre-configured agents and workflows
|
|
106
|
+
```
|
|
105
107
|
|
|
106
108
|
## Local Development
|
|
107
109
|
|
|
@@ -124,4 +126,4 @@ Born from our discussions in TechOverflow with [vichannnnn](https://github.com/v
|
|
|
124
126
|
|
|
125
127
|
## License
|
|
126
128
|
|
|
127
|
-
MIT
|
|
129
|
+
MIT
|
package/bin/create-project.js
CHANGED
|
@@ -807,17 +807,15 @@ async function main() {
|
|
|
807
807
|
'claude': [],
|
|
808
808
|
'agents': [],
|
|
809
809
|
'docs': [],
|
|
810
|
-
'plans': [],
|
|
811
810
|
'tickets': []
|
|
812
811
|
};
|
|
813
|
-
|
|
812
|
+
|
|
814
813
|
// Store conflict strategies per category
|
|
815
814
|
const conflictStrategies = {
|
|
816
815
|
'CLAUDE.md': 'skip',
|
|
817
816
|
'claude': 'skip',
|
|
818
817
|
'agents': 'skip',
|
|
819
818
|
'docs': 'skip',
|
|
820
|
-
'plans': 'skip',
|
|
821
819
|
'tickets': 'skip'
|
|
822
820
|
};
|
|
823
821
|
|
|
@@ -898,7 +896,7 @@ async function main() {
|
|
|
898
896
|
}
|
|
899
897
|
|
|
900
898
|
// Process claude subdirectories (except agents which we handle specially)
|
|
901
|
-
const claudeSubdirs = ['docs', '
|
|
899
|
+
const claudeSubdirs = ['docs', 'skills', 'tickets'];
|
|
902
900
|
claudeSubdirs.forEach(subdir => {
|
|
903
901
|
const subdirSrc = path.join(src, subdir);
|
|
904
902
|
const subdirDest = path.join(dest, subdir);
|
|
@@ -1033,8 +1031,8 @@ async function main() {
|
|
|
1033
1031
|
conflictsByCategory['agents'].push(relativePath);
|
|
1034
1032
|
} else if (relativePath.startsWith('claude/docs/')) {
|
|
1035
1033
|
conflictsByCategory['docs'].push(relativePath);
|
|
1036
|
-
} else if (relativePath.startsWith('claude/
|
|
1037
|
-
conflictsByCategory['
|
|
1034
|
+
} else if (relativePath.startsWith('claude/skills/')) {
|
|
1035
|
+
conflictsByCategory['docs'].push(relativePath);
|
|
1038
1036
|
} else if (relativePath.startsWith('claude/tickets/')) {
|
|
1039
1037
|
conflictsByCategory['tickets'].push(relativePath);
|
|
1040
1038
|
}
|
|
@@ -1073,7 +1071,6 @@ async function main() {
|
|
|
1073
1071
|
{ key: 'claude', name: 'Claude Directory', emoji: '📁' },
|
|
1074
1072
|
{ key: 'agents', name: 'Agents', emoji: '🤖' },
|
|
1075
1073
|
{ key: 'docs', name: 'Documentation', emoji: '📚' },
|
|
1076
|
-
{ key: 'plans', name: 'Plans', emoji: '📋' },
|
|
1077
1074
|
{ key: 'tickets', name: 'Tickets', emoji: '🎫' }
|
|
1078
1075
|
];
|
|
1079
1076
|
|
|
@@ -1140,8 +1137,8 @@ async function main() {
|
|
|
1140
1137
|
strategy = conflictStrategies['agents'];
|
|
1141
1138
|
} else if (item.relativePath.startsWith('claude/docs/')) {
|
|
1142
1139
|
strategy = conflictStrategies['docs'];
|
|
1143
|
-
} else if (item.relativePath.startsWith('claude/
|
|
1144
|
-
strategy = conflictStrategies['
|
|
1140
|
+
} else if (item.relativePath.startsWith('claude/skills/')) {
|
|
1141
|
+
strategy = conflictStrategies['docs'];
|
|
1145
1142
|
} else if (item.relativePath.startsWith('claude/tickets/')) {
|
|
1146
1143
|
strategy = conflictStrategies['tickets'];
|
|
1147
1144
|
} else {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccstart",
|
|
3
|
-
"version": "2.0
|
|
4
|
-
"description": "Start your Claude Code projects with a well-organized structure including agents, tickets,
|
|
3
|
+
"version": "2.2.0",
|
|
4
|
+
"description": "Start your Claude Code projects with a well-organized structure including agents, tickets, skills and orchestration workflows",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ccstart": "bin/create-project.js"
|
|
7
7
|
},
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
├── CLAUDE.md # This file - project instructions for Claude
|
|
20
20
|
├── .claude/ # Claude Code configuration (auto-generated)
|
|
21
21
|
│ ├── agents/ # Project-specific agent overrides
|
|
22
|
-
│ └──
|
|
22
|
+
│ └── skills/ # Skills for workflow automation
|
|
23
23
|
├── claude/ # Claude Code project organization
|
|
24
24
|
│ ├── agents/ # Custom agents for specialized tasks
|
|
25
25
|
│ ├── docs/ # Project documentation
|
|
26
|
-
│ ├──
|
|
26
|
+
│ ├── skills/ # Skill definitions (source of truth)
|
|
27
27
|
│ └── tickets/ # Task tickets and issues
|
|
28
28
|
└── [your project files and directories]
|
|
29
29
|
```
|
|
@@ -137,11 +137,23 @@ See @claude/agents/README.md for available agents and their purposes
|
|
|
137
137
|
|
|
138
138
|
After adding the agents you want to in `./claude/agents` folder, setup the workflow for Claude code to follow
|
|
139
139
|
|
|
140
|
-
##
|
|
140
|
+
## Skills
|
|
141
141
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
Skills extend Claude's capabilities with specialized workflows. Available skills:
|
|
143
|
+
|
|
144
|
+
**Git Workflow:**
|
|
145
|
+
- **/commit** - Generate and execute git commits following conventional commit format
|
|
146
|
+
- **/create-pr** - Create GitHub pull requests with structured descriptions
|
|
147
|
+
|
|
148
|
+
**Project Management:**
|
|
149
|
+
- **/create-ticket** - Create task tickets with proper numbering and update ticket-list.md
|
|
150
|
+
- **/design-feature** - Guide feature development through requirements and design phases
|
|
151
|
+
|
|
152
|
+
**Utilities:**
|
|
153
|
+
- **/design-principles** - Enforce a precise, minimal design system
|
|
154
|
+
- **/skill-creator** - Guide for creating new skills
|
|
155
|
+
|
|
156
|
+
See `claude/skills/` for skill definitions and `.claude/skills/` for Claude Code integration
|
|
145
157
|
|
|
146
158
|
## Tickets
|
|
147
159
|
|
|
@@ -155,15 +167,10 @@ See @claude/tickets/README.md for ticket format and management approach
|
|
|
155
167
|
- Complete a ticket (move to completed section with date)
|
|
156
168
|
- **Status Emojis**: 🔴 Todo | 🟡 In Progress | 🟢 Done | 🔵 Blocked | ⚫ Cancelled
|
|
157
169
|
|
|
158
|
-
## Plans
|
|
159
|
-
|
|
160
|
-
See @claude/plans/README.md for planning documents and architectural decisions
|
|
161
|
-
|
|
162
170
|
## Development Context
|
|
163
171
|
|
|
164
172
|
- See @claude/docs/ROADMAP.md for current status and next steps
|
|
165
173
|
- Task-based development workflow with tickets in `claude/tickets` directory
|
|
166
|
-
- Use `claude/plans` directory for architectural decisions and implementation roadmaps
|
|
167
174
|
|
|
168
175
|
## Important Instructions
|
|
169
176
|
|
|
@@ -171,10 +178,8 @@ Before starting any task:
|
|
|
171
178
|
|
|
172
179
|
1. **Confirm understanding**: Always confirm you understand the request and outline your plan before proceeding
|
|
173
180
|
2. **Ask clarifying questions**: Never make assumptions - ask questions when requirements are unclear
|
|
174
|
-
3. **
|
|
175
|
-
4. **
|
|
176
|
-
5. **No code comments**: Never add comments to any code you write - code should be self-documenting
|
|
177
|
-
6. **Maintain ticket list**: Always update @claude/tickets/ticket-list.md when creating, updating, or completing tickets to maintain a clear project overview
|
|
181
|
+
3. **No code comments**: Never add comments to any code you write - code should be self-documenting
|
|
182
|
+
4. **Maintain ticket list**: Always update @claude/tickets/ticket-list.md when creating, updating, or completing tickets to maintain a clear project overview
|
|
178
183
|
|
|
179
184
|
## Additional Notes
|
|
180
185
|
<!-- auto-generated-start:notes -->
|
|
@@ -26,10 +26,7 @@ Agents are specialized prompts or tools that help Claude perform specific tasks
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
## Available Agents
|
|
29
|
-
- **planner** - Strategic planning
|
|
30
|
-
- **
|
|
31
|
-
- **
|
|
32
|
-
- **
|
|
33
|
-
- **blockchain** - Blockchain and Web3 expert for smart contracts, DeFi protocols, and blockchain architecture
|
|
34
|
-
- **frontend** - Frontend development specialist for UI/UX, responsive design, and modern web frameworks
|
|
35
|
-
- **shadcn** - shadcn/ui component library expert for building beautiful, accessible React interfaces
|
|
29
|
+
- **planner** - Strategic planning and task breakdown specialist
|
|
30
|
+
- **checker** - Quality assurance and code review specialist
|
|
31
|
+
- **backend** - FastAPI and Python backend specialist
|
|
32
|
+
- **frontend** - React and TypeScript frontend specialist
|
|
@@ -1,80 +1,235 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: backend
|
|
3
|
-
description:
|
|
4
|
-
tools: Read, Write, Edit, Grep, Glob, Bash, WebSearch, WebFetch
|
|
3
|
+
description: FastAPI and Python backend specialist. Use for API endpoints, database models, authentication, and service logic. Invoke when building or modifying backend infrastructure.
|
|
5
4
|
---
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- **
|
|
23
|
-
- **
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- **
|
|
27
|
-
- **
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
6
|
+
# Backend Agent
|
|
7
|
+
|
|
8
|
+
Build backend services using FastAPI, SQLAlchemy 2.0, and PostgreSQL. Follow the patterns and conventions defined below strictly.
|
|
9
|
+
|
|
10
|
+
## When to Use This Agent
|
|
11
|
+
|
|
12
|
+
- Creating or modifying API endpoints
|
|
13
|
+
- Designing database models and schemas
|
|
14
|
+
- Implementing authentication and authorization
|
|
15
|
+
- Writing service layer business logic
|
|
16
|
+
- Adding validation, error handling, or pagination
|
|
17
|
+
- Database migrations with Alembic
|
|
18
|
+
|
|
19
|
+
## Stack
|
|
20
|
+
|
|
21
|
+
- **Framework**: FastAPI with async/await
|
|
22
|
+
- **ORM**: SQLAlchemy 2.0 async with asyncpg
|
|
23
|
+
- **Database**: PostgreSQL
|
|
24
|
+
- **Validation**: Pydantic v2
|
|
25
|
+
- **Auth**: JWT tokens in HTTP-only cookies, bcrypt password hashing
|
|
26
|
+
- **Migrations**: Alembic
|
|
27
|
+
|
|
28
|
+
## Project Structure
|
|
29
|
+
|
|
30
|
+
Follow this directory layout:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
app/
|
|
34
|
+
├── main.py # FastAPI app setup
|
|
35
|
+
├── config.py # Pydantic Settings for env vars
|
|
36
|
+
├── api/
|
|
37
|
+
│ ├── api.py # Router aggregation
|
|
38
|
+
│ ├── deps.py # Dependency injection (auth, session)
|
|
39
|
+
│ └── endpoints/
|
|
40
|
+
│ └── {resource}.py # One file per resource
|
|
41
|
+
├── models/
|
|
42
|
+
│ └── {resource}.py # SQLAlchemy models
|
|
43
|
+
├── schemas/
|
|
44
|
+
│ └── {resource}/
|
|
45
|
+
│ ├── request.py # Create/Update schemas
|
|
46
|
+
│ └── response.py # Response schemas
|
|
47
|
+
├── services/
|
|
48
|
+
│ └── {resource}.py # Business logic
|
|
49
|
+
├── crud/
|
|
50
|
+
│ └── base.py # Generic CRUD mixin
|
|
51
|
+
├── db/
|
|
52
|
+
│ └── database.py # Engine and session setup
|
|
53
|
+
├── utils/
|
|
54
|
+
│ ├── auth.py # JWT and password utilities
|
|
55
|
+
│ └── exceptions.py # AppError class
|
|
56
|
+
└── enum/
|
|
57
|
+
└── {name}.py # Enum definitions
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Implementation Patterns
|
|
61
|
+
|
|
62
|
+
### Router Structure
|
|
63
|
+
|
|
64
|
+
Create one router file per resource in `api/endpoints/`. Register in `api/api.py`:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
api_router = APIRouter()
|
|
68
|
+
api_router.include_router(auth.router, tags=["Authentication"], prefix="/auth")
|
|
69
|
+
api_router.include_router(books.router, tags=["Book"], prefix="/books")
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Endpoint Pattern
|
|
73
|
+
|
|
74
|
+
Use type-annotated dependencies. Keep endpoints thin—delegate to services:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
@router.post("", response_model=BookResponse)
|
|
78
|
+
async def create_book(
|
|
79
|
+
session: CurrentSession,
|
|
80
|
+
user: CurrentUser,
|
|
81
|
+
book: CreateBookRequest,
|
|
82
|
+
) -> BookResponse:
|
|
83
|
+
new_book = await BookService.create(session, data=book)
|
|
84
|
+
return BookResponse.model_validate(new_book)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Model Pattern
|
|
88
|
+
|
|
89
|
+
Use SQLAlchemy 2.0 with `Mapped` type hints. UUID primary keys. Inherit from `Base` and `CRUD`:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
class Book(Base, CRUD):
|
|
93
|
+
__tablename__ = "book"
|
|
94
|
+
|
|
95
|
+
book_id: Mapped[UUID] = mapped_column(
|
|
96
|
+
PG_UUID(as_uuid=True), primary_key=True, index=True, default=uuid4
|
|
97
|
+
)
|
|
98
|
+
title: Mapped[str] = mapped_column(nullable=False)
|
|
99
|
+
created_at: Mapped[datetime] = mapped_column(
|
|
100
|
+
DateTime(timezone=True), nullable=False, server_default=func.now()
|
|
101
|
+
)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Schema Pattern
|
|
105
|
+
|
|
106
|
+
Use Pydantic v2 with `CustomBaseModel`. Separate request and response schemas:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
class CreateBookRequest(CustomBaseModel):
|
|
110
|
+
title: str
|
|
111
|
+
author: str
|
|
112
|
+
|
|
113
|
+
class BookResponse(CustomBaseModel):
|
|
114
|
+
book_id: UUID
|
|
115
|
+
title: str
|
|
116
|
+
author: str
|
|
117
|
+
created_at: datetime
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Service Pattern
|
|
121
|
+
|
|
122
|
+
Static methods containing business logic. Never put business logic in endpoints:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
class BookService:
|
|
126
|
+
@staticmethod
|
|
127
|
+
async def create(session: AsyncSession, data: CreateBookRequest) -> Book:
|
|
128
|
+
book = Book(**data.model_dump())
|
|
129
|
+
session.add(book)
|
|
130
|
+
await session.commit()
|
|
131
|
+
await session.refresh(book)
|
|
132
|
+
return book
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Dependency Pattern
|
|
136
|
+
|
|
137
|
+
Define dependencies in `api/deps.py` using `Annotated`:
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
async def get_db_session() -> AsyncGenerator[AsyncSession, None]:
|
|
141
|
+
async with async_session() as session:
|
|
142
|
+
yield session
|
|
143
|
+
|
|
144
|
+
CurrentSession = Annotated[AsyncSession, Depends(get_db_session)]
|
|
145
|
+
CurrentUser = Annotated[UserMetadata, Depends(get_current_user)]
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Error Handling
|
|
149
|
+
|
|
150
|
+
Use centralized `AppError` class. Raise `HTTPException` with proper status codes:
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
class AppError:
|
|
154
|
+
RESOURCES_NOT_FOUND_ERROR = HTTPException(
|
|
155
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
156
|
+
detail="Resource not found",
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
@staticmethod
|
|
160
|
+
def bad_request(detail: str) -> HTTPException:
|
|
161
|
+
return HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=detail)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Pagination Pattern
|
|
165
|
+
|
|
166
|
+
Return paginated results with metadata:
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
@staticmethod
|
|
170
|
+
async def get_all_paginated(
|
|
171
|
+
session: AsyncSession, page: int = 1, size: int = 50
|
|
172
|
+
) -> dict[str, Any]:
|
|
173
|
+
skip = (page - 1) * size
|
|
174
|
+
total = await session.scalar(select(func.count()).select_from(Book))
|
|
175
|
+
result = await session.execute(select(Book).offset(skip).limit(size))
|
|
176
|
+
pages = (total + size - 1) // size if total else 0
|
|
177
|
+
return {
|
|
178
|
+
"items": result.scalars().all(),
|
|
179
|
+
"page": page,
|
|
180
|
+
"pages": pages,
|
|
181
|
+
"size": size,
|
|
182
|
+
"total": total,
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Authentication Pattern
|
|
187
|
+
|
|
188
|
+
JWT tokens stored in HTTP-only cookies. bcrypt for password hashing:
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
# Creating token
|
|
192
|
+
access_token = Authenticator.create_access_token(data=user_metadata.model_dump())
|
|
193
|
+
response.set_cookie(
|
|
194
|
+
key="access_token",
|
|
195
|
+
value=access_token,
|
|
196
|
+
httponly=True,
|
|
197
|
+
secure=True,
|
|
198
|
+
max_age=decoded_token["exp"],
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
# Verifying token
|
|
202
|
+
async def get_current_user(request: Request) -> UserMetadata:
|
|
203
|
+
token = request.cookies.get("access_token")
|
|
204
|
+
if not token:
|
|
205
|
+
raise AppError.INVALID_CREDENTIALS_ERROR
|
|
206
|
+
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
|
207
|
+
return UserMetadata.model_validate(payload)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Quality Standards
|
|
211
|
+
|
|
212
|
+
### Every Endpoint Must Have
|
|
213
|
+
- Response model defined
|
|
214
|
+
- Proper HTTP status codes
|
|
215
|
+
- Error handling for expected failures
|
|
216
|
+
- Type-annotated parameters
|
|
217
|
+
|
|
218
|
+
### Every Model Must Have
|
|
219
|
+
- UUID primary key
|
|
220
|
+
- Proper indexes on frequently queried columns
|
|
221
|
+
- `created_at` timestamp with `server_default=func.now()`
|
|
222
|
+
- Foreign keys with `index=True`
|
|
223
|
+
|
|
224
|
+
### Every Service Method Must
|
|
225
|
+
- Be a static method
|
|
226
|
+
- Accept session as first parameter
|
|
227
|
+
- Handle database errors and raise appropriate `AppError`
|
|
228
|
+
- Commit transactions explicitly
|
|
229
|
+
|
|
230
|
+
### Never Do
|
|
231
|
+
- Put business logic in endpoints
|
|
232
|
+
- Use raw SQL without parameterization
|
|
233
|
+
- Store passwords in plain text
|
|
234
|
+
- Return database models directly (use response schemas)
|
|
235
|
+
- Skip validation on user input
|