Skip to content

Commit 668cc15

Browse files
committed
feat: Add comprehensive API development, code patterns, and security guidelines documentation
- Introduced detailed documentation for API development patterns, including route organization, endpoint creation, and authentication flows. - Added code patterns and conventions for structuring Go applications, including repository-service-handler architecture and error handling. - Documented development workflow, including setup, daily commands, and testing strategies. - Established project structure guidelines, outlining core architecture layers and package organization. - Introduced security patterns covering authentication, authorization, input validation, and vulnerability management best practices.
1 parent 77c5f93 commit 668cc15

File tree

5 files changed

+658
-0
lines changed

5 files changed

+658
-0
lines changed

.cursor/rules/api-development.mdc

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
---
2+
description: API development
3+
globs:
4+
alwaysApply: false
5+
---
6+
# API Development Patterns
7+
8+
## Route Organization in Main
9+
Routes are defined in [cmd/api/main.go](mdc:cmd/api/main.go) with clear groupings:
10+
11+
### Public Routes
12+
- No authentication required
13+
- Registration, login, password reset
14+
- Social OAuth callbacks
15+
16+
### Protected Routes
17+
- Require JWT authentication via `middleware.AuthMiddleware()`
18+
- User profile, logout, 2FA management
19+
- Activity logs
20+
21+
### Admin Routes
22+
- Protected with auth middleware
23+
- Future role-based access control
24+
25+
## Adding New API Endpoints
26+
27+
### 1. Create DTOs
28+
Define request/response structures in `pkg/dto/`:
29+
```go
30+
type CreateSomethingRequest struct {
31+
Name string `json:"name" validate:"required" example:"Sample Name"`
32+
Description string `json:"description,omitempty" example:"Sample description"`
33+
}
34+
35+
type SomethingResponse struct {
36+
ID uint `json:"id" example:"1"`
37+
Name string `json:"name" example:"Sample Name"`
38+
CreatedAt string `json:"created_at" example:"2023-01-01T00:00:00Z"`
39+
}
40+
```
41+
42+
### 2. Add Handler with Swagger Annotations
43+
```go
44+
// CreateSomething creates a new something
45+
// @Summary Create something
46+
// @Description Create a new something with the provided data
47+
// @Tags something
48+
// @Accept json
49+
// @Produce json
50+
// @Param request body dto.CreateSomethingRequest true "Something data"
51+
// @Success 201 {object} dto.APIResponse{data=dto.SomethingResponse}
52+
// @Failure 400 {object} dto.APIResponse
53+
// @Security ApiKeyAuth
54+
// @Router /something [post]
55+
func (h *Handler) CreateSomething(c *gin.Context) {
56+
// Implementation
57+
}
58+
```
59+
60+
### 3. Register Route
61+
Add to appropriate group in [cmd/api/main.go](mdc:cmd/api/main.go):
62+
```go
63+
protected.POST("/something", handler.CreateSomething)
64+
```
65+
66+
### 4. Regenerate Documentation
67+
```bash
68+
make swag-init
69+
```
70+
71+
## Authentication Patterns
72+
73+
### JWT Middleware
74+
- Applied to protected routes in [cmd/api/main.go](mdc:cmd/api/main.go)
75+
- Validates JWT tokens and extracts user information
76+
- Sets user context for handlers
77+
78+
### 2FA Flow
79+
- Temporary tokens for 2FA verification
80+
- Separate verification endpoint
81+
- Recovery code support
82+
83+
### Social Authentication
84+
- OAuth2 flow with state verification
85+
- Provider-specific callbacks
86+
- User linking/creation logic
87+
88+
## Response Format Standards
89+
90+
### Success Response
91+
```go
92+
{
93+
"success": true,
94+
"data": {...}
95+
}
96+
```
97+
98+
### Error Response
99+
```go
100+
{
101+
"success": false,
102+
"error": "descriptive error message"
103+
}
104+
```
105+
106+
## Input Validation
107+
- Use `go-playground/validator` tags in DTOs
108+
- Validate in handlers before service calls
109+
- Return appropriate HTTP status codes
110+
111+
## Activity Logging
112+
- Log security-relevant events
113+
- Include user ID, IP address, user agent
114+
- Use structured logging format
115+
- Examples: login attempts, password changes, 2FA events
116+
117+
## Database Operations
118+
- Use GORM models from `pkg/models/`
119+
- Repository pattern for data access
120+
- Transaction support for multi-step operations
121+
- Proper error handling and logging
122+

.cursor/rules/code-patterns.mdc

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
---
2+
description: Code patterns
3+
globs:
4+
alwaysApply: false
5+
---
6+
# Go Code Patterns and Conventions
7+
8+
## Architecture Pattern: Repository-Service-Handler
9+
10+
### Repository Layer
11+
```go
12+
type Repository interface {
13+
Create(entity *Entity) error
14+
GetByID(id uint) (*Entity, error)
15+
Update(entity *Entity) error
16+
Delete(id uint) error
17+
}
18+
19+
type repository struct {
20+
db *gorm.DB
21+
}
22+
23+
func NewRepository(db *gorm.DB) Repository {
24+
return &repository{db: db}
25+
}
26+
```
27+
28+
### Service Layer
29+
```go
30+
type Service interface {
31+
BusinessOperation(input Input) (*Output, error)
32+
}
33+
34+
type service struct {
35+
repo Repository
36+
// other dependencies
37+
}
38+
39+
func NewService(repo Repository) Service {
40+
return &service{repo: repo}
41+
}
42+
```
43+
44+
### Handler Layer
45+
```go
46+
type Handler struct {
47+
service Service
48+
}
49+
50+
func NewHandler(service Service) *Handler {
51+
return &Handler{service: service}
52+
}
53+
54+
// @Summary Operation description
55+
// @Router /endpoint [method]
56+
func (h *Handler) HandlerMethod(c *gin.Context) {
57+
// Request binding
58+
// Validation
59+
// Service call
60+
// Response
61+
}
62+
```
63+
64+
## Dependency Injection Pattern
65+
66+
### Constructor Functions
67+
All components use constructor functions with dependency injection:
68+
```go
69+
func NewService(repo Repository, emailService EmailService) Service {
70+
return &service{
71+
repo: repo,
72+
emailService: emailService,
73+
}
74+
}
75+
```
76+
77+
### Main Function Organization
78+
In [cmd/api/main.go](mdc:cmd/api/main.go):
79+
1. Initialize infrastructure (DB, Redis)
80+
2. Create repositories
81+
3. Create services with dependencies
82+
4. Create handlers
83+
5. Setup routes
84+
85+
## Error Handling Patterns
86+
87+
### Custom Error Types
88+
Define in `pkg/errors/`:
89+
```go
90+
type AuthError struct {
91+
Code string
92+
Message string
93+
Err error
94+
}
95+
96+
func (e *AuthError) Error() string {
97+
return e.Message
98+
}
99+
```
100+
101+
### Error Response Pattern
102+
```go
103+
if err != nil {
104+
c.JSON(http.StatusBadRequest, gin.H{
105+
"success": false,
106+
"error": err.Error(),
107+
})
108+
return
109+
}
110+
```
111+
112+
### Success Response Pattern
113+
```go
114+
c.JSON(http.StatusOK, gin.H{
115+
"success": true,
116+
"data": result,
117+
})
118+
```
119+
120+
## Database Patterns
121+
122+
### GORM Models
123+
Located in `pkg/models/`:
124+
```go
125+
type User struct {
126+
ID uint `gorm:"primaryKey" json:"id"`
127+
Email string `gorm:"unique;not null" json:"email"`
128+
Password string `gorm:"not null" json:"-"`
129+
CreatedAt time.Time `json:"created_at"`
130+
UpdatedAt time.Time `json:"updated_at"`
131+
}
132+
```
133+
134+
### Repository Methods
135+
```go
136+
func (r *repository) GetByEmail(email string) (*models.User, error) {
137+
var user models.User
138+
if err := r.db.Where("email = ?", email).First(&user).Error; err != nil {
139+
return nil, err
140+
}
141+
return &user, nil
142+
}
143+
```
144+
145+
## DTO (Data Transfer Object) Patterns
146+
147+
### Request DTOs
148+
```go
149+
type LoginRequest struct {
150+
Email string `json:"email" validate:"required,email" example:"user@example.com"`
151+
Password string `json:"password" validate:"required,min=8" example:"password123"`
152+
}
153+
```
154+
155+
### Response DTOs
156+
```go
157+
type UserResponse struct {
158+
ID uint `json:"id" example:"1"`
159+
Email string `json:"email" example:"user@example.com"`
160+
CreatedAt string `json:"created_at" example:"2023-01-01T00:00:00Z"`
161+
}
162+
```
163+
164+
## Swagger Documentation Pattern
165+
166+
### Handler Annotations
167+
```go
168+
// @Summary User login
169+
// @Description Authenticate user with email and password
170+
// @Tags authentication
171+
// @Accept json
172+
// @Produce json
173+
// @Param request body dto.LoginRequest true "Login credentials"
174+
// @Success 200 {object} dto.APIResponse{data=dto.LoginResponse}
175+
// @Failure 400 {object} dto.APIResponse
176+
// @Router /login [post]
177+
```
178+
179+
## Configuration Pattern
180+
181+
### Environment Variables
182+
Using Viper in [cmd/api/main.go](mdc:cmd/api/main.go):
183+
```go
184+
viper.AutomaticEnv()
185+
viper.SetDefault("PORT", "8080")
186+
viper.SetDefault("ACCESS_TOKEN_EXPIRATION_MINUTES", 15)
187+
```
188+
189+
## Testing Patterns
190+
191+
### Table-Driven Tests
192+
```go
193+
func TestService_Method(t *testing.T) {
194+
tests := []struct {
195+
name string
196+
input Input
197+
want Output
198+
wantErr bool
199+
}{
200+
// test cases
201+
}
202+
203+
for _, tt := range tests {
204+
t.Run(tt.name, func(t *testing.T) {
205+
// test implementation
206+
})
207+
}
208+
}
209+
```
210+
211+
### Mock Interfaces
212+
Use interfaces for all dependencies to enable mocking in tests.
213+
214+
## Security Code Patterns
215+
216+
### Password Hashing
217+
```go
218+
func HashPassword(password string) (string, error) {
219+
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
220+
return string(bytes), err
221+
}
222+
```
223+
224+
### JWT Token Generation
225+
```go
226+
func GenerateToken(userID uint, tokenType string) (string, error) {
227+
claims := jwt.MapClaims{
228+
"user_id": userID,
229+
"type": tokenType,
230+
"exp": time.Now().Add(expiration).Unix(),
231+
}
232+
// token generation logic
233+
}
234+
```
235+
236+
## Activity Logging Pattern
237+
238+
### Log Service Usage
239+
```go
240+
logService.LogActivity(logService.ActivityLogParams{
241+
UserID: userID,
242+
EventType: "login_success",
243+
Description: "User logged in successfully",
244+
IPAddress: c.ClientIP(),
245+
UserAgent: c.GetHeader("User-Agent"),
246+
})
247+
```
248+
249+
## File Organization Rules
250+
251+
### Package Structure
252+
- One responsibility per package
253+
- Internal packages in `internal/`
254+
- Shared packages in `pkg/`
255+
- Feature-based organization
256+
257+
### File Naming
258+
- `handler.go` for HTTP handlers
259+
- `service.go` for business logic
260+
- `repository.go` for data access
261+
- `models.go` for database models
262+
- `dto.go` for data transfer objects
263+

0 commit comments

Comments
 (0)