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

Được viết bởi admin vào ngày 13/11/2025 lúc 06:11 | 131 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
admin

admin

Biên tập viên, Hướng Nghiệp Dữ Liệu
737 Bài viết
15.4k Người theo dõi
120k+ Lượt đọc

Biên tập viên nội dung tại Hướng Nghiệp Dữ Liệu, phụ trách tổng hợp và biên soạn các bài viết về lập trình Python, dữ liệu và công nghệ.