Ví dụ thực tế: Xây dựng REST API Backend
Scenario
Yêu cầu: Xây dựng REST API cho hệ thống quản lý task (Task Management System)
Features:
- User authentication (JWT)
- CRUD tasks
- Assign tasks to users
- Task status tracking
- Due date reminders
Cách 1: KHÔNG dùng one-toolkit
Timeline: 5 ngày
Day 1: Nhảy thẳng vào code
Developer: "Tạo REST API cho task management với auth, CRUD tasks, assignments"
AI: "Sure! Here's the code..."AI sinh code ngay:
// user.model.ts
export class User {
id: string;
email: string;
password: string; // Plain text - SECURITY ISSUE!
}
// task.controller.ts
@Controller('tasks')
export class TaskController {
@Post()
async create(@Body() data: any) { // No validation!
return this.taskService.create(data);
}
@Get()
async findAll() {
return this.taskService.findAll(); // No pagination!
}
}
// auth.service.ts
async login(email: string, password: string) {
const user = await this.findByEmail(email);
if (user.password === password) { // Plain text comparison!
return { token: 'some-token' }; // Hardcoded token!
}
}Vấn đề:
- ❌ Password không được hash
- ❌ Không có validation
- ❌ Không có pagination
- ❌ Token hardcoded
- ❌ Không có error handling
- ❌ Không có documentation
Day 2: Phát hiện vấn đề, refactor
Developer: "Ủa, password phải hash chứ?"
AI: "Oh yes, let me fix that..."AI refactor:
// auth.service.ts
import * as bcrypt from 'bcrypt'; // Thêm dependency mới
async login(email: string, password: string) {
const user = await this.findByEmail(email);
const isValid = await bcrypt.compare(password, user.password);
if (isValid) {
const token = jwt.sign({ userId: user.id }, 'secret'); // Secret hardcoded!
return { token };
}
}Vấn đề mới:
- ❌ Secret key hardcoded
- ❌ Không có token expiry
- ❌ Không có refresh token
Day 3: Tiếp tục fix
Developer: "Secret key phải để trong env, thêm refresh token"
AI: "OK, updating..."Refactor lần 2:
// auth.service.ts
async login(email: string, password: string) {
const user = await this.findByEmail(email);
const isValid = await bcrypt.compare(password, user.password);
if (isValid) {
const accessToken = jwt.sign(
{ userId: user.id },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
const refreshToken = jwt.sign(
{ userId: user.id },
process.env.JWT_REFRESH_SECRET,
{ expiresIn: '7d' }
);
return { accessToken, refreshToken };
}
}Vấn đề:
- ❌ Refresh token không được lưu DB (không thể revoke)
- ❌ Không có rate limiting
- ❌ Không có audit log
Day 4: Thêm features, phát hiện thêm vấn đề
Developer: "Implement task assignment"
AI: *implement*
Developer: "Test thử... Ủa, sao user A assign được task cho user B mà không check permission?"
AI: "Let me add authorization..."Thêm authorization:
// task.controller.ts
@Post(':id/assign')
async assign(@Param('id') id: string, @Body() data: any) {
// Thêm logic check permission
const task = await this.taskService.findOne(id);
if (task.createdBy !== currentUser.id) {
throw new ForbiddenException(); // Vừa mới thêm
}
return this.taskService.assign(id, data.userId);
}Vấn đề:
- ❌ Authorization logic nằm rải rác trong controllers
- ❌ Không consistent
- ❌ Khó maintain
Day 5: Viết tests (cuối cùng)
Developer: "Viết tests đi"
AI: *viết tests*Tests:
describe('TaskController', () => {
it('should create task', async () => {
const result = await controller.create(mockData);
expect(result).toBeDefined(); // Test quá đơn giản
});
// Coverage: 45%
// Nhiều edge cases không được test
});Vấn đề:
- ❌ Coverage thấp (45%)
- ❌ Không test edge cases
- ❌ Không test authorization
- ❌ Không test error scenarios
Kết quả sau 5 ngày
Code:
src/
├── controllers/
│ ├── auth.controller.ts (refactored 3 lần)
│ ├── task.controller.ts (refactored 4 lần)
│ └── user.controller.ts (refactored 2 lần)
├── services/
│ ├── auth.service.ts (refactored 3 lần)
│ ├── task.service.ts (refactored 3 lần)
│ └── user.service.ts (refactored 2 lần)
└── __tests__/
└── task.test.ts (coverage: 45%)Vấn đề tồn tại:
- ❌ Không có documentation
- ❌ Không biết tại sao chọn architecture này
- ❌ Authorization logic không consistent
- ❌ Security issues vẫn còn (rate limiting, audit log)
- ❌ Test coverage thấp
- ❌ Code bị refactor nhiều lần → technical debt cao
Thời gian:
- Coding: 3 ngày
- Refactoring: 1.5 ngày
- Testing: 0.5 ngày
- Total: 5 ngày
Code quality: ⭐⭐ (2/5)
Cách 2: DÙNG one-toolkit
Timeline: 4 ngày
Day 1 Morning: Requirements Phase
one-toolkit init --allDeveloper: /new-requirement
AI: "What is the feature name?"
Developer: "task-management-api"
AI: "Creating documentation structure..."
AI: "What problem does this solve?"
Developer: "Teams need to track tasks, assign work, and monitor progress"
AI: "Let me help you write detailed requirements..."AI điền vào docs/agent/requirements/feature-task-management-api.md:
## Problem Statement
Teams lack a centralized system to track tasks, assign work to members,
and monitor progress. Current solution (spreadsheets) is inefficient and
doesn't support real-time collaboration.
## User Stories
### Authentication
- As a user, I want to register an account so that I can use the system
- As a user, I want to login securely so that my data is protected
- As a user, I want to refresh my token so that I don't have to login frequently
### Task Management
- As a user, I want to create tasks so that I can track my work
- As a user, I want to view all my tasks so that I can see what needs to be done
- As a user, I want to update task status so that I can track progress
- As a user, I want to delete tasks so that I can remove completed/cancelled work
### Task Assignment
- As a task owner, I want to assign tasks to team members so that work is distributed
- As an assignee, I want to see tasks assigned to me so that I know what to work on
- As a task owner, I want to reassign tasks so that I can adjust workload
### Notifications
- As a user, I want to receive reminders for due tasks so that I don't miss deadlines
## Success Criteria
- User can register and login in < 5 seconds
- API response time < 200ms
- Support 1000+ concurrent users
- 99.9% uptime
- All passwords encrypted
- JWT tokens with refresh mechanism
- Tasks can be filtered by status, assignee, due date
- Email notifications for due tasks
## Constraints
- Must use JWT for authentication
- Must support PostgreSQL database
- Must follow REST API best practices
- Must have comprehensive error handling
- Must have audit logging
## Security Requirements
- Passwords must be hashed (bcrypt)
- JWT tokens must expire (15 min access, 7 day refresh)
- Rate limiting on auth endpoints (5 attempts/minute)
- Authorization checks on all endpoints
- Audit log for sensitive operations
## Edge Cases
- What if user tries to assign task they don't own?
- What if user tries to delete task with assignees?
- What if token expires during operation?
- What if user changes password (invalidate all tokens)?
- What if multiple users update same task simultaneously?
## Open Questions
- Should we support task comments?
- Should we support file attachments?
- Should we support task dependencies?
→ Decided: Not in v1, add to backlogTime: 2 hours
Day 1 Afternoon: Design Phase
Developer: /review-design
AI: "Based on requirements, proposing architecture..."AI tạo docs/agent/design/feature-task-management-api.md:
## Architecture Overview
```mermaid
graph TD
Client[Client App] -->|HTTPS| Gateway[API Gateway]
Gateway --> Auth[Auth Service]
Gateway --> Task[Task Service]
Gateway --> Notif[Notification Service]
Auth --> UserDB[(User DB)]
Auth --> TokenDB[(Token Store - Redis)]
Task --> TaskDB[(Task DB)]
Task --> Queue[Message Queue]
Queue --> Notif
Notif --> Email[Email Service]
Task --> Audit[Audit Service]
Audit --> AuditDB[(Audit Log)]Data Models
// User Model
interface User {
id: string;
email: string;
passwordHash: string;
name: string;
createdAt: Date;
updatedAt: Date;
}
// Task Model
interface Task {
id: string;
title: string;
description?: string;
status: 'todo' | 'in_progress' | 'done';
priority: 'low' | 'medium' | 'high';
createdBy: string; // User ID
assignedTo?: string; // User ID
dueDate?: Date;
createdAt: Date;
updatedAt: Date;
}
// RefreshToken Model
interface RefreshToken {
id: string;
userId: string;
token: string;
expiresAt: Date;
createdAt: Date;
}
// AuditLog Model
interface AuditLog {
id: string;
userId: string;
action: string;
resource: string;
resourceId: string;
timestamp: Date;
metadata: Record<string, any>;
}API Design
Authentication Endpoints
POST /api/auth/register
POST /api/auth/login
POST /api/auth/refresh
POST /api/auth/logoutTask Endpoints
POST /api/tasks - Create task
GET /api/tasks - List tasks (with filters)
GET /api/tasks/:id - Get task details
PUT /api/tasks/:id - Update task
DELETE /api/tasks/:id - Delete task
POST /api/tasks/:id/assign - Assign taskRequest/Response Examples
POST /api/auth/register
Request:
{
"email": "user@example.com",
"password": "SecurePass123!",
"name": "John Doe"
}
Response 201:
{
"id": "user_123",
"email": "user@example.com",
"name": "John Doe",
"createdAt": "2024-01-15T10:00:00Z"
}POST /api/auth/login
Request:
{
"email": "user@example.com",
"password": "SecurePass123!"
}
Response 200:
{
"accessToken": "eyJhbGc...",
"refreshToken": "eyJhbGc...",
"expiresIn": 900
}POST /api/tasks
Request:
{
"title": "Implement user authentication",
"description": "Add JWT-based auth",
"priority": "high",
"dueDate": "2024-01-20"
}
Response 201:
{
"id": "task_123",
"title": "Implement user authentication",
"status": "todo",
"priority": "high",
"createdBy": "user_123",
"dueDate": "2024-01-20",
"createdAt": "2024-01-15T10:00:00Z"
}Design Decisions
Why PostgreSQL?
- Need ACID transactions
- Complex queries (filters, joins)
- Strong data consistency
- Mature ecosystem
Why Redis for token storage?
- Fast access for token validation
- Built-in expiration (TTL)
- Reduce DB load
- Easy to scale
Why separate Audit Service?
- Decouple audit logic from business logic
- Can scale independently
- Easier to query audit logs
- Compliance requirements
Why Message Queue for notifications?
- Async processing (don't block API)
- Retry failed notifications
- Can add more notification channels later (SMS, push)
Authorization Strategy
- Use middleware for authentication (verify JWT)
- Use guards for authorization (check permissions)
- Resource-based access control:
- Task owner can: update, delete, assign
- Task assignee can: update status
- Others: read-only (if public)
Security Measures
Password Security
- Hash with bcrypt (salt rounds: 10)
- Minimum length: 8 characters
- Must contain: uppercase, lowercase, number, special char
Token Security
- Access token: 15 minutes expiry
- Refresh token: 7 days expiry
- Store refresh tokens in DB (can revoke)
- Invalidate all tokens on password change
Rate Limiting
- Auth endpoints: 5 requests/minute per IP
- API endpoints: 100 requests/minute per user
- Use Redis for rate limit counters
Input Validation
- Use class-validator for DTO validation
- Sanitize all inputs
- Validate email format
- Validate date formats
Non-Functional Requirements
Performance
- API response time: < 200ms (p95)
- Database queries: < 50ms
- Use indexes on frequently queried fields
- Use caching for user data (Redis)
Scalability
- Stateless API (can scale horizontally)
- Database connection pooling
- Message queue for async tasks
Reliability
- Graceful error handling
- Retry logic for external services
- Health check endpoints
- Logging at all layers
Monitoring
- Log all API requests
- Log all errors with stack traces
- Audit log for sensitive operations
- Metrics: response time, error rate, active users
**Time**: 3 hours
#### Day 1 End: Planning PhaseDeveloper: /update-planning AI: "Breaking down design into tasks..."
**AI tạo** `docs/agent/planning/feature-task-management-api.md`:
```markdown
## Task Breakdown
### Milestone 1: Project Setup (Est: 0.5 day)
- [ ] Initialize NestJS project
- [ ] Setup PostgreSQL database
- [ ] Setup Redis
- [ ] Configure environment variables
- [ ] Setup TypeORM
- [ ] Create database migrations
- [ ] Setup logging (Winston)
### Milestone 2: Authentication (Est: 1 day)
- [ ] Create User entity
- [ ] Create RefreshToken entity
- [ ] Implement password hashing (bcrypt)
- [ ] Implement JWT service
- [ ] Implement POST /auth/register
- [ ] Implement POST /auth/login
- [ ] Implement POST /auth/refresh
- [ ] Implement POST /auth/logout
- [ ] Add input validation (DTOs)
- [ ] Add rate limiting
- [ ] Add error handling
### Milestone 3: Authorization Middleware (Est: 0.5 day)
- [ ] Create JWT auth guard
- [ ] Create role-based guard
- [ ] Add user context to requests
- [ ] Test middleware
### Milestone 4: Task Management (Est: 1 day)
- [ ] Create Task entity
- [ ] Implement POST /tasks
- [ ] Implement GET /tasks (with filters, pagination)
- [ ] Implement GET /tasks/:id
- [ ] Implement PUT /tasks/:id
- [ ] Implement DELETE /tasks/:id
- [ ] Implement POST /tasks/:id/assign
- [ ] Add authorization checks
- [ ] Add input validation
- [ ] Add error handling
### Milestone 5: Audit Logging (Est: 0.5 day)
- [ ] Create AuditLog entity
- [ ] Create audit interceptor
- [ ] Log sensitive operations
- [ ] Add audit endpoints (admin only)
### Milestone 6: Notification System (Est: 0.5 day)
- [ ] Setup message queue (Bull)
- [ ] Create notification service
- [ ] Implement email notifications
- [ ] Create cron job for due date reminders
### Milestone 7: Testing (Est: 1 day)
- [ ] Unit tests for auth service
- [ ] Unit tests for task service
- [ ] Integration tests for auth endpoints
- [ ] Integration tests for task endpoints
- [ ] E2E tests for critical flows
- [ ] Test authorization scenarios
- [ ] Test error scenarios
### Milestone 8: Documentation & Polish (Est: 0.5 day)
- [ ] API documentation (Swagger)
- [ ] README with setup instructions
- [ ] Environment variables documentation
- [ ] Deployment guide
## Dependencies
```mermaid
graph TD
A[Project Setup] --> B[Authentication]
A --> C[Authorization Middleware]
B --> D[Task Management]
C --> D
D --> E[Audit Logging]
D --> F[Notification System]
E --> G[Testing]
F --> G
G --> H[Documentation]Implementation Order
- Project Setup (blocking)
- Authentication (blocking)
- Authorization Middleware (blocking)
- Task Management (blocking)
- Audit Logging (parallel with Notification)
- Notification System (parallel with Audit)
- Testing (after all features)
- Documentation (final)
Effort Estimates
| Milestone | Effort | Priority |
|---|---|---|
| Project Setup | 0.5 day | P0 |
| Authentication | 1 day | P0 |
| Authorization | 0.5 day | P0 |
| Task Management | 1 day | P0 |
| Audit Logging | 0.5 day | P1 |
| Notifications | 0.5 day | P1 |
| Testing | 1 day | P0 |
| Documentation | 0.5 day | P2 |
| Total | 5.5 days |
Note: With one-toolkit structure, estimate is 4 days due to fewer refactors.
Risks & Mitigation
| Risk | Mitigation |
|---|---|
| Token invalidation complexity | Use Redis for token blacklist |
| Concurrent task updates | Use optimistic locking (version field) |
| Email delivery failures | Retry with exponential backoff |
| Database migration issues | Test in staging first, have rollback plan |
**Time**: 2 hours
**Day 1 Total**: 7 hours (Requirements + Design + Planning)
#### Day 2-3: Implementation PhaseDeveloper: /execute-plan AI: "Starting task execution..." AI: "Task 1: Initialize NestJS project"
**AI implement theo plan**, với context đầy đủ từ design doc:
```typescript
// src/auth/auth.service.ts
// Implemented according to design doc
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcrypt';
@Injectable()
export class AuthService {
constructor(
private userService: UserService,
private jwtService: JwtService,
private refreshTokenService: RefreshTokenService,
) {}
async register(dto: RegisterDto): Promise<User> {
// Validate email not exists
const exists = await this.userService.findByEmail(dto.email);
if (exists) {
throw new ConflictException('Email already exists');
}
// Hash password (bcrypt, 10 rounds as per design)
const passwordHash = await bcrypt.hash(dto.password, 10);
// Create user
const user = await this.userService.create({
email: dto.email,
name: dto.name,
passwordHash,
});
// Audit log
await this.auditService.log({
userId: user.id,
action: 'USER_REGISTERED',
resource: 'user',
resourceId: user.id,
});
return user;
}
async login(dto: LoginDto): Promise<TokenResponse> {
// Find user
const user = await this.userService.findByEmail(dto.email);
if (!user) {
throw new UnauthorizedException('Invalid credentials');
}
// Verify password
const isValid = await bcrypt.compare(dto.password, user.passwordHash);
if (!isValid) {
throw new UnauthorizedException('Invalid credentials');
}
// Generate tokens (15 min access, 7 day refresh as per design)
const accessToken = this.jwtService.sign(
{ userId: user.id },
{ expiresIn: '15m' },
);
const refreshToken = this.jwtService.sign(
{ userId: user.id },
{ secret: process.env.JWT_REFRESH_SECRET, expiresIn: '7d' },
);
// Store refresh token in DB (for revocation)
await this.refreshTokenService.create({
userId: user.id,
token: refreshToken,
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
});
// Audit log
await this.auditService.log({
userId: user.id,
action: 'USER_LOGIN',
resource: 'auth',
resourceId: user.id,
});
return {
accessToken,
refreshToken,
expiresIn: 900, // 15 minutes
};
}
// ... other methods following design doc
}Lợi ích:
- ✅ Code follow design doc chính xác
- ✅ Security measures đầy đủ (hash, expiry, audit)
- ✅ Error handling proper
- ✅ Không cần refactor vì đã design kỹ
AI update implementation notes vào docs/agent/implementation/feature-task-management-api.md:
## Implementation Notes
### Authentication Implementation
- Used bcrypt with 10 salt rounds (as per design)
- JWT tokens stored in Redis for fast validation
- Refresh tokens stored in PostgreSQL for revocation
- All sensitive operations logged to audit table
### Patterns Used
- Repository pattern for data access
- DTO pattern for validation
- Service layer for business logic
- Interceptor for audit logging
- Guard for authorization
### Error Handling Strategy
- Use NestJS built-in exceptions
- Custom exception filter for consistent error format
- Log all errors with context
- Return user-friendly messages (no stack traces to client)
### Performance Optimizations
- Database indexes on: email, userId, taskId, status
- Redis caching for user data (5 min TTL)
- Connection pooling (max 20 connections)
- Pagination for list endpoints (default 20 items)Time: 2 days (implementation smooth vì có design rõ ràng)
Day 4: Testing Phase
Developer: /writing-test
AI: "Generating tests based on requirements..."AI viết tests cover tất cả requirements:
// src/auth/__tests__/auth.service.spec.ts
describe('AuthService', () => {
describe('register', () => {
it('should register user with hashed password', async () => {
const dto = {
email: 'test@example.com',
password: 'SecurePass123!',
name: 'Test User',
};
const result = await service.register(dto);
expect(result.email).toBe(dto.email);
expect(result.passwordHash).not.toBe(dto.password); // Hashed
expect(result.passwordHash).toMatch(/^\$2[aby]\$/); // bcrypt format
});
it('should throw ConflictException if email exists', async () => {
mockUserService.findByEmail.mockResolvedValue(existingUser);
await expect(service.register(dto)).rejects.toThrow(ConflictException);
});
it('should log audit entry on registration', async () => {
await service.register(dto);
expect(mockAuditService.log).toHaveBeenCalledWith({
userId: expect.any(String),
action: 'USER_REGISTERED',
resource: 'user',
resourceId: expect.any(String),
});
});
});
describe('login', () => {
it('should return tokens on valid credentials', async () => {
const result = await service.login(loginDto);
expect(result.accessToken).toBeDefined();
expect(result.refreshToken).toBeDefined();
expect(result.expiresIn).toBe(900); // 15 minutes
});
it('should throw UnauthorizedException on invalid password', async () => {
mockUserService.findByEmail.mockResolvedValue(user);
bcrypt.compare = jest.fn().mockResolvedValue(false);
await expect(service.login(loginDto)).rejects.toThrow(
UnauthorizedException,
);
});
it('should store refresh token in database', async () => {
await service.login(loginDto);
expect(mockRefreshTokenService.create).toHaveBeenCalledWith({
userId: user.id,
token: expect.any(String),
expiresAt: expect.any(Date),
});
});
// Test rate limiting
it('should block after 5 failed attempts', async () => {
for (let i = 0; i < 5; i++) {
await service.login(invalidDto).catch(() => {});
}
await expect(service.login(invalidDto)).rejects.toThrow(
TooManyRequestsException,
);
});
});
});
// Integration tests
describe('AuthController (e2e)', () => {
it('POST /auth/register should create user', () => {
return request(app.getHttpServer())
.post('/auth/register')
.send({
email: 'test@example.com',
password: 'SecurePass123!',
name: 'Test User',
})
.expect(201)
.expect((res) => {
expect(res.body.email).toBe('test@example.com');
expect(res.body.passwordHash).toBeUndefined(); // Not exposed
});
});
it('POST /auth/login should return tokens', () => {
return request(app.getHttpServer())
.post('/auth/login')
.send({
email: 'test@example.com',
password: 'SecurePass123!',
})
.expect(200)
.expect((res) => {
expect(res.body.accessToken).toBeDefined();
expect(res.body.refreshToken).toBeDefined();
});
});
// Test authorization
it('GET /tasks should require authentication', () => {
return request(app.getHttpServer())
.get('/tasks')
.expect(401);
});
it('GET /tasks should work with valid token', () => {
return request(app.getHttpServer())
.get('/tasks')
.set('Authorization', `Bearer ${validToken}`)
.expect(200);
});
// Test edge cases from requirements
it('should not allow assigning task user does not own', async () => {
const task = await createTask(user1);
return request(app.getHttpServer())
.post(`/tasks/${task.id}/assign`)
.set('Authorization', `Bearer ${user2Token}`)
.send({ assignedTo: user3.id })
.expect(403);
});
});Coverage report:
File | % Stmts | % Branch | % Funcs | % Lines |
------------------------|---------|----------|---------|---------|
auth.service.ts | 98.5 | 95.2 | 100 | 98.7 |
task.service.ts | 97.8 | 93.5 | 100 | 97.9 |
auth.controller.ts | 100 | 100 | 100 | 100 |
task.controller.ts | 98.2 | 94.1 | 100 | 98.3 |
------------------------|---------|----------|---------|---------|
Total | 98.1 | 94.7 | 100 | 98.2 |Time: 1 day
Kết quả sau 4 ngày
Code structure:
project/
├── docs/
│ └── agent/
│ ├── requirements/
│ │ └── feature-task-management-api.md ✅
│ ├── design/
│ │ └── feature-task-management-api.md ✅
│ ├── planning/
│ │ └── feature-task-management-api.md ✅
│ ├── implementation/
│ │ └── feature-task-management-api.md ✅
│ └── testing/
│ └── feature-task-management-api.md ✅
├── src/
│ ├── auth/
│ │ ├── auth.service.ts
│ │ ├── auth.controller.ts
│ │ ├── jwt.strategy.ts
│ │ ├── dto/
│ │ └── __tests__/
│ ├── tasks/
│ │ ├── task.service.ts
│ │ ├── task.controller.ts
│ │ ├── dto/
│ │ └── __tests__/
│ ├── audit/
│ └── notifications/
├── .one-toolkit.json
└── README.mdChất lượng:
- ✅ Đầy đủ documentation
- ✅ Security measures đúng chuẩn
- ✅ Test coverage 98%
- ✅ Code không bị refactor (design tốt từ đầu)
- ✅ Authorization consistent
- ✅ Error handling đầy đủ
- ✅ Audit logging complete
Thời gian:
- Requirements: 0.25 ngày
- Design: 0.25 ngày
- Planning: 0.25 ngày
- Implementation: 2 ngày
- Testing: 1 ngày
- Total: 4 ngày
Code quality: ⭐⭐⭐⭐⭐ (5/5)
So sánh tổng quan
| Tiêu chí | Không dùng toolkit | Dùng one-toolkit | Chênh lệch |
|---|---|---|---|
| Thời gian | 5 ngày | 4 ngày | -20% |
| Số lần refactor | 15+ lần | 2-3 lần | -80% |
| Test coverage | 45% | 98% | +118% |
| Documentation | Không có | Đầy đủ | ∞ |
| Security issues | 5+ issues | 0 issues | -100% |
| Code quality | 2/5 | 5/5 | +150% |
| Technical debt | Cao | Thấp | -70% |
| Maintainability | Khó | Dễ | +200% |
Chất lượng code và tư duy khác nhau ra sao
Tư duy
Không dùng toolkit:
"Làm nhanh đã, sửa sau"
→ Code → Bug → Fix → Bug → Fix → ...
→ Reactive thinkingDùng one-toolkit:
"Suy nghĩ trước, code sau"
→ Requirements → Design → Plan → Code → Test
→ Proactive thinkingChất lượng code
Không dùng toolkit:
- Code bị refactor nhiều → inconsistent
- Security issues phát hiện muộn
- Tests viết sau → coverage thấp
- Không có documentation → khó maintain
Dùng one-toolkit:
- Code consistent từ đầu (follow design)
- Security được design từ đầu
- Tests viết song song → coverage cao
- Documentation đầy đủ → dễ maintain
Output khác nhau
Không dùng toolkit:
project/
└── src/
└── *.ts (code only, no docs)Dùng one-toolkit:
project/
├── docs/agent/ ← Đầy đủ documentation
│ ├── requirements/
│ ├── design/
│ ├── planning/
│ ├── implementation/
│ └── testing/
└── src/
└── *.ts (clean code + tests)ROI (Return on Investment)
Không dùng toolkit:
- Thời gian dev: 5 ngày
- Thời gian maintain: 10 ngày (vì thiếu docs, nhiều bugs)
- Total: 15 ngày
Dùng one-toolkit:
- Thời gian dev: 4 ngày
- Thời gian maintain: 2 ngày (vì có docs, ít bugs)
- Total: 6 ngày
Tiết kiệm: 60%
Kết luận
one-toolkit không phải là magic tool làm code nhanh hơn. Nó là framework giúp bạn:
- Suy nghĩ có hệ thống trước khi code
- Giảm refactor vì design tốt từ đầu
- Tăng chất lượng vì có quy trình rõ ràng
- Dễ maintain vì có documentation đầy đủ
Trade-off:
- Phải spend thời gian ở phase đầu (requirements, design)
- Nhưng tiết kiệm được nhiều thời gian ở phase sau (implementation, testing, maintenance)
Khi nào đáng dùng:
- ✅ Project dài hạn (> 1 tháng)
- ✅ Team > 1 người
- ✅ Cần chất lượng cao
- ✅ Cần maintain lâu dài
Khi nào không cần:
- ❌ Prototype nhanh (< 1 ngày)
- ❌ Script đơn giản
- ❌ Deadline cực gấp
Tiếp theo: Phân tích ưu điểm cốt lõi của one-toolkit → Xem phần tiếp theo.