ccstart 2.1.0 → 3.0.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 +83 -58
- package/bin/create-project.js +478 -110
- package/package.json +3 -12
- package/template/claude/CLAUDE.md +16 -105
- package/template/claude/agents/README.md +4 -7
- package/template/claude/agents/backend.md +231 -75
- package/template/claude/agents/checker.md +76 -50
- package/template/claude/agents/frontend.md +295 -68
- package/template/claude/agents/planner.md +86 -31
- package/template/claude/hooks/claude-md-reminder.sh +15 -0
- package/template/claude/hooks/ticket-reminder.sh +19 -0
- package/template/claude/skills/create-script/SKILL.md +362 -0
- package/template/claude/skills/design-feature/SKILL.md +3 -3
- package/template/claude/skills/skill-creator/SKILL.md +1 -1
- package/template/claude/agents/blockchain.md +0 -80
- package/template/claude/agents/coder.md +0 -45
- package/template/claude/agents/researcher.md +0 -55
- package/template/claude/agents/shadcn.md +0 -105
- package/template/claude/docs/ROADMAP.md +0 -64
- package/template/claude/docs/agent-orchestration.md +0 -152
- package/template/claude/skills/design-principles/skill.md +0 -237
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccstart",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Start your Claude Code projects with a well-organized structure including agents, tickets,
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "Start your Claude Code projects with a well-organized structure including agents, tickets, and skills",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ccstart": "bin/create-project.js"
|
|
7
7
|
},
|
|
@@ -16,8 +16,7 @@
|
|
|
16
16
|
"author": "vichannnnn",
|
|
17
17
|
"contributors": [
|
|
18
18
|
"marcia_ong",
|
|
19
|
-
"hima7459"
|
|
20
|
-
"nasdin"
|
|
19
|
+
"hima7459"
|
|
21
20
|
],
|
|
22
21
|
"license": "MIT",
|
|
23
22
|
"repository": {
|
|
@@ -35,13 +34,5 @@
|
|
|
35
34
|
},
|
|
36
35
|
"dependencies": {
|
|
37
36
|
"@inquirer/checkbox": "^4.0.4"
|
|
38
|
-
},
|
|
39
|
-
"devDependencies": {
|
|
40
|
-
"jest": "^30.0.5"
|
|
41
|
-
},
|
|
42
|
-
"scripts": {
|
|
43
|
-
"test": "jest",
|
|
44
|
-
"test:watch": "jest --watch",
|
|
45
|
-
"test:coverage": "jest --coverage"
|
|
46
37
|
}
|
|
47
38
|
}
|
|
@@ -17,13 +17,12 @@
|
|
|
17
17
|
```
|
|
18
18
|
.
|
|
19
19
|
├── CLAUDE.md # This file - project instructions for Claude
|
|
20
|
-
├── .
|
|
21
|
-
|
|
22
|
-
│
|
|
23
|
-
├──
|
|
24
|
-
│
|
|
25
|
-
|
|
26
|
-
│ ├── plans/ # Project plans and architectural documents
|
|
20
|
+
├── ROADMAP.md # Project roadmap and goals
|
|
21
|
+
├── .claude/ # Claude Code configuration
|
|
22
|
+
│ ├── agents/ # Specialized agents for Claude Code
|
|
23
|
+
│ ├── skills/ # Skills for workflow automation
|
|
24
|
+
│ └── hooks/ # Event hooks for Claude Code
|
|
25
|
+
├── claude/ # Project organization
|
|
27
26
|
│ └── tickets/ # Task tickets and issues
|
|
28
27
|
└── [your project files and directories]
|
|
29
28
|
```
|
|
@@ -42,79 +41,6 @@
|
|
|
42
41
|
- Add tests for new functionality
|
|
43
42
|
- Ensure all tests pass
|
|
44
43
|
|
|
45
|
-
### Git Workflow
|
|
46
|
-
|
|
47
|
-
- Create descriptive commit messages
|
|
48
|
-
- Keep commits focused and atomic
|
|
49
|
-
- Review changes before committing
|
|
50
|
-
|
|
51
|
-
## Commit Convention and Pull Request Guidelines
|
|
52
|
-
|
|
53
|
-
### Commit Message Format
|
|
54
|
-
Follow the conventional commits specification:
|
|
55
|
-
```
|
|
56
|
-
<type>(<scope>): <subject>
|
|
57
|
-
|
|
58
|
-
<body>
|
|
59
|
-
|
|
60
|
-
<footer>
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
**Types:**
|
|
64
|
-
- `feat`: New feature
|
|
65
|
-
- `fix`: Bug fix
|
|
66
|
-
- `docs`: Documentation changes
|
|
67
|
-
- `style`: Code style changes (formatting, missing semicolons, etc.)
|
|
68
|
-
- `refactor`: Code refactoring without changing functionality
|
|
69
|
-
- `test`: Adding or modifying tests
|
|
70
|
-
- `chore`: Maintenance tasks (updating dependencies, build process, etc.)
|
|
71
|
-
- `perf`: Performance improvements
|
|
72
|
-
|
|
73
|
-
**Examples:**
|
|
74
|
-
```
|
|
75
|
-
feat(auth): add password reset functionality
|
|
76
|
-
fix(api): handle null values in user response
|
|
77
|
-
docs: update API documentation for book endpoints
|
|
78
|
-
refactor(frontend): extract BookTable into separate components
|
|
79
|
-
chore(deps): update FastAPI to 0.104.1
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### Pull Request Guidelines
|
|
83
|
-
|
|
84
|
-
**PR Title**: Use the same format as commit messages
|
|
85
|
-
|
|
86
|
-
**PR Description Template:**
|
|
87
|
-
```markdown
|
|
88
|
-
## Summary
|
|
89
|
-
Brief description of what this PR does and why it's needed.
|
|
90
|
-
|
|
91
|
-
## Changes
|
|
92
|
-
- List of specific changes made
|
|
93
|
-
- Technical implementation details if relevant
|
|
94
|
-
|
|
95
|
-
## Testing
|
|
96
|
-
- [ ] Tests pass (if applicable)
|
|
97
|
-
- [ ] Manual testing completed
|
|
98
|
-
- [ ] No console errors or warnings
|
|
99
|
-
|
|
100
|
-
## Manual Testing Steps
|
|
101
|
-
1. Describe steps to manually test the feature
|
|
102
|
-
2. Expected behavior and edge cases tested
|
|
103
|
-
|
|
104
|
-
## Screenshots (if UI changes)
|
|
105
|
-
Attach relevant screenshots here
|
|
106
|
-
|
|
107
|
-
## Related Issues
|
|
108
|
-
Closes #XXX (if applicable)
|
|
109
|
-
|
|
110
|
-
## Checklist
|
|
111
|
-
- [ ] Code follows project conventions
|
|
112
|
-
- [ ] Self-documented code without unnecessary comments
|
|
113
|
-
- [ ] All tests pass
|
|
114
|
-
- [ ] Documentation updated if needed
|
|
115
|
-
- [ ] No sensitive information exposed
|
|
116
|
-
```
|
|
117
|
-
|
|
118
44
|
## Common Commands
|
|
119
45
|
<!-- auto-generated-start:commands -->
|
|
120
46
|
```bash
|
|
@@ -129,32 +55,24 @@ Closes #XXX (if applicable)
|
|
|
129
55
|
|
|
130
56
|
[Add any project-specific context, dependencies, or requirements here]
|
|
131
57
|
|
|
132
|
-
##
|
|
58
|
+
## Skills
|
|
133
59
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
## Agent Orchestration
|
|
137
|
-
|
|
138
|
-
After adding the agents you want to in `./claude/agents` folder, setup the workflow for Claude code to follow
|
|
139
|
-
|
|
140
|
-
## Custom Commands
|
|
141
|
-
|
|
142
|
-
Custom slash commands are available in `.claude/commands/`:
|
|
60
|
+
Skills extend Claude's capabilities with specialized workflows. Available skills:
|
|
143
61
|
|
|
144
62
|
**Git Workflow:**
|
|
145
63
|
- **/commit** - Generate and execute git commits following conventional commit format
|
|
146
64
|
- **/create-pr** - Create GitHub pull requests with structured descriptions
|
|
147
|
-
- **/review-pr** - Review pull requests with systematic quality checks
|
|
148
65
|
|
|
149
66
|
**Project Management:**
|
|
150
67
|
- **/create-ticket** - Create task tickets with proper numbering and update ticket-list.md
|
|
151
68
|
- **/design-feature** - Guide feature development through requirements and design phases
|
|
152
|
-
- **/create-plan** - Create timestamped planning documents
|
|
153
69
|
|
|
154
70
|
**Utilities:**
|
|
155
|
-
- **/
|
|
71
|
+
- **/create-script** - Codify processes into standalone Python scripts with CLI interfaces
|
|
72
|
+
- **/skill-creator** - Guide for creating new skills
|
|
73
|
+
- **/update-claude-md** - Update CLAUDE.md sections through interactive Q&A
|
|
156
74
|
|
|
157
|
-
See `.claude/
|
|
75
|
+
See `.claude/skills/` for skill definitions
|
|
158
76
|
|
|
159
77
|
## Tickets
|
|
160
78
|
|
|
@@ -168,26 +86,19 @@ See @claude/tickets/README.md for ticket format and management approach
|
|
|
168
86
|
- Complete a ticket (move to completed section with date)
|
|
169
87
|
- **Status Emojis**: 🔴 Todo | 🟡 In Progress | 🟢 Done | 🔵 Blocked | ⚫ Cancelled
|
|
170
88
|
|
|
171
|
-
## Plans
|
|
172
|
-
|
|
173
|
-
See @claude/plans/README.md for planning documents and architectural decisions
|
|
174
|
-
|
|
175
89
|
## Development Context
|
|
176
90
|
|
|
177
|
-
- See @
|
|
91
|
+
- See @ROADMAP.md for current status and next steps
|
|
178
92
|
- Task-based development workflow with tickets in `claude/tickets` directory
|
|
179
|
-
- Use `claude/plans` directory for architectural decisions and implementation roadmaps
|
|
180
93
|
|
|
181
94
|
## Important Instructions
|
|
182
95
|
|
|
183
96
|
Before starting any task:
|
|
184
97
|
|
|
185
98
|
1. **Confirm understanding**: Always confirm you understand the request and outline your plan before proceeding
|
|
186
|
-
2. **Ask clarifying questions**: Never make assumptions - ask questions when requirements are unclear
|
|
187
|
-
3. **
|
|
188
|
-
4. **
|
|
189
|
-
5. **No code comments**: Never add comments to any code you write - code should be self-documenting
|
|
190
|
-
6. **Maintain ticket list**: Always update @claude/tickets/ticket-list.md when creating, updating, or completing tickets to maintain a clear project overview
|
|
99
|
+
2. **Ask clarifying questions**: Never make assumptions - always ask questions when requirements are unclear
|
|
100
|
+
3. **No code comments**: Never add comments to any code you write - code should be self-documenting
|
|
101
|
+
4. **Maintain ticket list**: Always update @claude/tickets/ticket-list.md when creating, updating, or completing tickets to maintain a clear project overview
|
|
191
102
|
|
|
192
103
|
## Additional Notes
|
|
193
104
|
<!-- 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,79 +1,235 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: backend
|
|
3
|
-
description: Backend
|
|
3
|
+
description: Backend architecture and API design specialist. Use for API endpoints, database models, authentication, and service logic. Invoke when building or modifying backend infrastructure.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
|
|
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
|
-
|
|
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
|