In team environments, there's often a need for rotating responsibilities such as treating colleagues, daily duties, or handling specific tasks. In our team particularly, we have a tradition of Thursday treats. However, with team personnel changes, ensuring fair distribution of treating duties became a technical challenge that needed to be solved.
To address this, I developed "Thursday Treating Calendar"—a modern React application focused on managing the team's weekly treating schedule, with special emphasis on Thursday treating events.
技术栈选择 | Technology Stack
项目采用了以下技术栈:
The project utilizes the following technology stack:
前端框架 | Frontend Framework: React + TypeScript,利用强类型提高代码质量和开发效率 (leveraging strong typing to improve code quality and development efficiency)
构建工具 | Build Tool: Vite,享受其快速的开发和构建体验 (enjoying its fast development and build experience)
状态管理 | State Management: Zustand,轻量级且易用的状态管理库 (lightweight and easy-to-use state management library)
后端数据库 | Backend Database: Supabase,作为Backend-as-a-Service解决方案 (as a Backend-as-a-Service solution)
边缘计算 | Edge Computing: Edge Functions,在CDN边缘节点运行无服务器函数,降低延迟,提高性能 (serverless functions running at CDN edge nodes, reducing latency and improving performance)
1. 人员管理与自动调度 | Personnel Management and Automatic Scheduling
系统允许添加、删除和管理团队成员,自动生成平衡的请客安排表。这里采用了两种调度方法:
The system allows adding, removing, and managing team members, automatically generating balanced treating schedules. Two scheduling methods are implemented:
基于名称的排序 | Name-based Sorting: 按字母顺序排序,但考虑计算值 (sorts alphabetically by name, but considers calculated values)
随机排序 | Random Sorting: 随机分配,但优先考虑计算值低的成员 (randomly assigns, but prioritizes members with lower calculated values)
2. 公平分配系统 - hostOffset机制 | Fair Distribution System - hostOffset Mechanism
这是系统最核心的设计,解决了当新成员加入团队时如何确保公平性的问题:
This is the core design of the system, solving the fairness issue when new members join the team:
// Each person has two important values:// 1. hostingCount: Actual number of times they've treated// 2. hostOffset: An offset value for fair calculationconst calculatePriority = (person) => { return person.hostingCount + person.hostOffset}
When new members join, they receive a hostOffset value equal to the minimum "calculated value" (hostingCount + hostOffset) among all existing members. This ensures:
新成员不会因为刚加入就获得不公平的优势 (New members don't get an unfair advantage just because they've just joined)
新成员不会一加入就立即承担请客责任 (New members aren't immediately burdened with treating duties upon joining)
To ensure team members remember their treating duties, the system integrates Resend API to send reminder emails. As a modern email delivery solution, Resend API offers high reliability, good deliverability, and a clean developer experience, perfectly meeting the notification needs of the project:
// Email notification system using Resend APIconst sendReminder = async (host, date) => { // Get template from database const template = await getEmailTemplate('reminder') // Replace placeholders with actual values const htmlContent = template.html_content .replace('{{hostName}}', host.name) .replace('{{date}}', formatDate(date)) // Send email using Resend API await resend.emails.send({ from: 'noreply@example.com', to: host.email, subject: template.subject, html: htmlContent, })}
Combined with Edge Functions, the email notification system can process requests efficiently with low latency, maintaining excellent performance even on a global scale.
4. 数据库设计 | Database Design
项目使用Supabase作为后端,设计了四个主要表:
The project uses Supabase as the backend, with four main tables designed:
personnel表:存储人员信息及其请客历史记录 (stores personnel information and their treating history)
The project uses Zustand as the state management solution. Compared to traditional solutions like Redux, Zustand provides a more concise API and less boilerplate code:
In this project, Zustand manages all core states, including personnel lists, schedules, UI states, etc., and provides a series of business logic methods such as adding/removing personnel, generating schedules, swapping schedules, etc. This centralized state management makes component code more concise and business logic clearer.
部署与运维 | Deployment and Operations
项目采用Vercel进行部署,这提供了简单的CI/CD流程和良好的性能。部署配置相对简单:
The project is deployed using Vercel, which provides a simple CI/CD process and good performance. The deployment configuration is relatively straightforward:
Through developing this project, I not only solved a real team need but also deeply practiced the combined application of React, TypeScript, and Supabase. The design of the hostOffset mechanism is the highlight of the entire project, solving a seemingly simple but actually complex fairness problem.
This project also made me realize that technical solutions should start from practical needs—even seemingly simple rotation arrangements can be made more fair and efficient through sound technical design.