Bài viết gần đây

| Hướng Dẫn Thực Tập SportSpot API Platform

Được viết bởi thanhdt vào ngày 13/11/2025 lúc 06:11 | 6 lượt xem

Tài Liệu Hướng Dẫn Thực Tập – SportSpot API Platform

1. 📋 Thông Tin Dự Án End User

Tên dự án: SportSpot – Nền tảng đặt sân thể thao
Công nghệ: Node.js, Express, MongoDB, React, Flutter
Môi trường: Development & Production Ready
Database: MongoDB với Mongoose ODM
Website: SportSpot


🎯 Mục Tiêu Thực Tập

1. Kiến Thức Cần Nắm Vững

  • Backend API Development với Node.js/Express
  • Database Design và quản lý MongoDB
  • Authentication & Authorization với Session
  • RESTful API design patterns
  • Error Handling và logging
  • API Documentation và testing

2. Kỹ Năng Phát Triển

  • Thiết kế database schema phù hợp
  • Xây dựng API endpoints hiệu quả
  • Implement authentication flow
  • Testing API với Postman/curl
  • Debug và troubleshoot issues
  • Code documentation và best practices

🏗️ Kiến Trúc Hệ Thống

Backend Structure

server/
├── index.ts          # Entry point
├── routes.ts         # API routes definition
├── mongoStorage.ts   # Database operations
├── db.ts            # MongoDB schema definitions
└── middleware/      # Authentication & validation

Database Schema

Users (người dùng)
├── Authentication info
├── Profile details
└── Verification status

SportCategories (danh mục thể thao)
├── Name, description
└── Icon & display info

Facilities (cơ sở thể thao)
├── Basic info (name, address, images)
├── Pricing & capacity
└── Operating hours

SportFields (sân cụ thể)
├── Field details (type, surface, size)
├── Status & availability
└── Linked to facility

PriceTables (bảng giá)
├── Time-based pricing
├── Customer type pricing
└── Weekend/weekday rates

Bookings (đặt sân)
├── Customer information
├── Selected time slots
├── Payment & pricing details
└── Status tracking

🛠️ Các API Endpoints Chính

1. Authentication APIs

POST /api/auth/register    # Đăng ký tài khoản
POST /api/auth/login       # Đăng nhập
POST /api/auth/logout      # Đăng xuất
GET  /api/auth/me          # Lấy thông tin user hiện tại

2. Facilities & Categories APIs

GET /api/categories        # Lấy danh mục thể thao
GET /api/facilities        # Lấy danh sách cơ sở thể thao
GET /api/facilities/:id    # Chi tiết cơ sở thể thao
GET /api/facilities/:id/pricing  # Lấy bảng giá theo thời gian

3. Booking APIs

POST /api/bookings/enhanced          # Tạo booking mới (format Flutter)
GET  /api/bookings/recent           # Lấy lịch sử booking
GET  /api/facilities/:id/bookings   # Booking theo cơ sở thể thao
GET  /api/fields/:id/booked-slots   # Lấy slot đã đặt theo sân

4. Admin APIs

GET  /api/bookings/:id     # Chi tiết booking
PUT  /api/bookings/:id     # Cập nhật booking
DELETE /api/bookings/:id   # Hủy booking

💻 Hướng Dẫn Development

1. Setup Môi Trường

# Clone project
git clone [repository-url]
cd sportspot

# Install dependencies
npm install

# Setup environment variables
cp .env.example .env
# Cấu hình DATABASE_URL, SESSION_SECRET, etc.

# Start development server
npm run dev

2. Database Development

// Tạo schema mới trong db.ts
const newSchema = new mongoose.Schema({
  field1: { type: String, required: true },
  field2: { type: Number, default: 0 },
  timestamps: true
});

// Export model
export const NewModel = mongoose.model('NewModel', newSchema);

3. API Development Pattern

// 1. Định nghĩa route trong routes.ts
app.get("/api/endpoint", async (req, res) => {
  try {
    // Validation
    const { param } = req.params;
    const { query } = req.query;

    // Business logic
    const result = await storage.methodName(param, query);

    // Response
    res.json(result);
  } catch (error) {
    console.error("Error:", error);
    res.status(500).json({ message: "Internal server error" });
  }
});

// 2. Implement logic trong mongoStorage.ts
async methodName(param: string, query?: string): Promise<ResultType> {
  try {
    const data = await Model.find({ conditions });
    return data.map(item => ({
      // Transform data
    }));
  } catch (error) {
    console.error("Database error:", error);
    throw error;
  }
}

🧪 Testing Guidelines

1. API Testing với Postman

// Test Enhanced Booking API
POST http://localhost:5000/api/bookings/enhanced
{
  "facilityId": "6821c96b3946d6bda8bd87e8",
  "selectedSlots": [
    {
      "fieldId": "682bb2af35339cbc051f6f5",
      "timeRange": "06:30-07:30",
      "price": 350000
    }
  ],
  "bookingDate": "2025-05-27",
  "totalPrice": 350000,
  "customerName": "Test User",
  "customerEmail": "test@example.com",
  "customerPhone": "0123456789"
}

2. Testing với cURL

# Login
curl -X POST http://localhost:5000/api/auth/login 
  -H "Content-Type: application/json" 
  -c cookies.txt 
  -d '{"username": "tamtest", "password": "123456"}'

# Test API với session
curl -X GET http://localhost:5000/api/bookings/recent 
  -H "Content-Type: application/json" 
  -b cookies.txt

📊 Database Operations

1. CRUD Operations

// Create
const newItem = new Model(data);
await newItem.save();

// Read
const items = await Model.find(query)
  .populate('relatedField')
  .sort({ createdAt: -1 });

// Update
await Model.findByIdAndUpdate(id, updateData, { new: true });

// Delete
await Model.findByIdAndDelete(id);

2. Advanced Queries

// Date range query
const bookings = await Booking.find({
  bookingDate: {
    $gte: startDate,
    $lt: endDate
  }
});

// Text search
const facilities = await Facility.find({
  $or: [
    { name: { $regex: searchTerm, $options: 'i' }},
    { address: { $regex: searchTerm, $options: 'i' }}
  ]
});

// Aggregation
const stats = await Booking.aggregate([
  { $match: { status: 'confirmed' }},
  { $group: { _id: '$facilityId', total: { $sum: '$totalPrice' }}}
]);

🔐 Authentication Flow

1. Session-based Authentication

// Login endpoint
app.post("/api/auth/login", async (req, res) => {
  const { username, password } = req.body;

  // Verify credentials
  const user = await storage.getUserByUsername(username);
  const isValid = await bcrypt.compare(password, user.password);

  if (isValid) {
    // Set session
    req.session.user = { id: user._id, username: user.username };
    res.json(userInfo);
  } else {
    res.status(401).json({ message: "Invalid credentials" });
  }
});

// Protected route middleware
const requireAuth = (req, res, next) => {
  if (!req.session.user) {
    return res.status(401).json({ message: "Not authenticated" });
  }
  next();
};

📱 Flutter Integration

1. Enhanced Booking Format

{
  "facilityId": "facility_id",
  "selectedSlots": [
    {
      "fieldId": "field_id",           // ID sân cụ thể
      "timeRange": "06:30-07:30",      // Khung giờ
      "price": 350000                  // Giá slot này
    }
  ],
  "bookingDate": "2025-05-27",
  "totalPrice": 350000,
  "totalDuration": 60,                 // Phút
  "customerName": "Tên khách hàng",
  "customerEmail": "email@example.com",
  "customerPhone": "0123456789",
  "customerType": "Khách vãng lai"
}

2. Response Format

{
  "id": "booking_id",
  "userId": "user_id",
  "facilityId": "facility_id",
  "selectedSlots": [
    {
      "fieldId": "field_id",
      "timeRange": "06:30-07:30",
      "price": 350000
    }
  ],
  "status": "pending",
  "totalPrice": 350000,
  "customerInfo": "...",
  "createdAt": "2025-05-27T...",
  "facility": {
    "name": "Tên cơ sở",
    "address": "Địa chỉ"
  }
}

⚠️ Error Handling Best Practices

1. Error Response Format

// Standard error response
{
  "message": "Human readable error message",
  "code": "ERROR_CODE",
  "details": "Additional error details"
}

// Validation error response
{
  "message": "Validation failed",
  "errors": [
    {
      "field": "fieldName",
      "message": "Field specific error"
    }
  ]
}

2. Error Handling Pattern

try {
  // Business logic
  const result = await operationThatMightFail();
  res.json(result);
} catch (error) {
  // Log error for debugging
  console.error("Operation failed:", error);

  // Return appropriate error response
  if (error.name === 'ValidationError') {
    res.status(400).json({ message: "Invalid input data" });
  } else if (error.name === 'CastError') {
    res.status(400).json({ message: "Invalid ID format" });
  } else {
    res.status(500).json({ message: "Internal server error" });
  }
}

📈 Performance Optimization

1. Database Indexing

// Tạo index cho truy vấn thường xuyên
facilitySchema.index({ name: 'text', address: 'text' });
bookingSchema.index({ facilityId: 1, bookingDate: 1 });
userSchema.index({ username: 1 }, { unique: true });

2. Query Optimization

// Sử dụng lean() cho read-only queries
const facilities = await Facility.find(query).lean();

// Limit fields với select()
const users = await User.find().select('name email phone');

// Pagination
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 10;
const skip = (page - 1) * limit;

const results = await Model.find(query)
  .skip(skip)
  .limit(limit);

📝 Documentation Standards

1. API Documentation Format

/**
 * GET /api/facilities/:id/bookings
 * 
 * Lấy danh sách booking của một cơ sở thể thao
 * 
 * @param {string} id - ID của cơ sở thể thao
 * @query {string} date - Ngày cần lọc (YYYY-MM-DD) - optional
 * 
 * @returns {Array} Danh sách booking
 * @example
 * // Request
 * GET /api/facilities/123/bookings?date=2025-05-27
 * 
 * // Response
 * [
 *   {
 *     "id": "booking_id",
 *     "customerName": "Tên khách",
 *     "selectedSlots": [...],
 *     "totalPrice": 350000
 *   }
 * ]
 */

2. Code Comments

// Xử lý logic đặt sân với multiple time slots
const processBookingSlots = (selectedSlots) => {
  // Validate từng slot
  selectedSlots.forEach(slot => {
    if (!slot.fieldId || !slot.timeRange) {
      throw new Error('Missing required slot data');
    }
  });

  // Tính tổng thời gian và giá
  const totalDuration = calculateTotalDuration(selectedSlots);
  const totalPrice = selectedSlots.reduce((sum, slot) => sum + slot.price, 0);

  return { totalDuration, totalPrice };
};

🎯 Assignments cho Thực Tập Sinh

Week 1: Setup & Understanding

  • [ ] Setup development environment
  • [ ] Understand project structure
  • [ ] Run và test existing APIs
  • [ ] Study database schema
  • [ ] Create first simple API endpoint

Week 2: CRUD Operations

  • [ ] Implement facility management APIs
  • [ ] Add field validation
  • [ ] Create search functionality
  • [ ] Practice error handling
  • [ ] Write API documentation

Week 3: Advanced Features

  • [ ] Implement booking system
  • [ ] Add authentication middleware
  • [ ] Create reporting APIs
  • [ ] Optimize database queries
  • [ ] Add logging system

Week 4: Integration & Testing

  • [ ] Test with Flutter app
  • [ ] Fix integration issues
  • [ ] Performance optimization
  • [ ] Deploy to staging
  • [ ] Final documentation

📚 Tài Liệu Tham Khảo

1. Technologies

2. Best Practices

3. Testing Tools


🔧 Troubleshooting Common Issues

1. Database Connection Issues

// Check MongoDB connection
if (mongoose.connection.readyState !== 1) {
  console.error('MongoDB not connected');
  // Implement reconnection logic
}

2. Session Problems

// Debug session issues
app.use((req, res, next) => {
  console.log('Session:', req.session);
  console.log('User:', req.session?.user);
  next();
});

3. CORS Issues

// Enable CORS for development
app.use(cors({
  origin: 'http://localhost:3000',
  credentials: true
}));

🎖️ Đánh Giá & Tiến Độ

Tiêu Chí Đánh Giá

  1. Code Quality (30%)

    • Clean, readable code
    • Proper error handling
    • Following best practices
  2. API Functionality (25%)

    • Correct implementation
    • Proper HTTP status codes
    • Data validation
  3. Database Design (20%)

    • Efficient queries
    • Proper relationships
    • Data integrity
  4. Documentation (15%)

    • API documentation
    • Code comments
    • User guides
  5. Problem Solving (10%)

    • Debugging skills
    • Independent learning
    • Creative solutions

Milestone Checkpoints

  • Week 1: Environment setup + Basic understanding
  • Week 2: First working API endpoints
  • Week 3: Complete booking system
  • Week 4: Integration testing + Deployment

Liên hệ hỗ trợ:

  • Email: support@sportspot.com
  • Slack: #dev-team
  • Documentation: [Internal Wiki]

Happy Coding! 🚀

2. 📋 Thông Tin Dự Án Admin

Thông tin admin: thanhdt9279@gmail.com / 123456

📊 Tổng thể nhân sự bao gồm:

  1. Team DB và Backend:

    • 1 Database (DB)
    • 1 API
      Do Thành và Vũ phụ trách backend (DB + API)
  2. 🖥️ Giao diện và chức năng Web Admin:
    Trang tổng quan (Dashboard + trạng thái sân)

    • 1 UI Web: Đã có
    • 1 FE Web: Do Chiến đảm nhiệm
  3. 📱 Giao diện và chức năng App Admin:

    • 1 UI App: Đạt
    • 1 FE App: Chưa