跪拜 Guibai
← All articles
JavaScript · Node.js · WeChat Mini Program

A WeChat Mini Program That Replaces Spreadsheets and Group-Chat Relays for Event Management

By JasonMa153 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

The unified-table-plus-JSON pattern is a practical alternative to single-table inheritance or polymorphic associations when you need to support multiple similar-but-distinct entity types without constant schema migrations. The automatic `ended`-state detection on read — rather than a cron job — is a low-overhead trick that works well for moderate-traffic apps where eventual consistency is acceptable.

Summary

Shubu is a production WeChat Mini Program built to replace the messy spreadsheets and group-chat relays that dominate community event organization in China. It packages five independent tools — event registration, time-slot service booking, activity relays with +1 support, entry/exit registration with approval, and real-time queue number calling — behind a shared user system and notification pipeline. The frontend uses native WeChat Mini Program APIs with Vant Weapp for UI components, while the backend runs on Express, Sequelize, and MySQL 8.4, with JWT-based dual-role authentication for admins and silent-login users.

The database design avoids table sprawl by storing all five tool types in a single activity table. Common fields like title, status, and creator sit in standard columns; tool-specific configuration lives in a JSON `extra` column. Each tool gets its own participation-record table linked by activity ID. Activity status transitions — draft, pending review, active, ended, paused — are enforced server-side, with the `ended` state detected on every detail request rather than via a scheduled job, eliminating a common source of drift.

The first installment of a seven-part series covers architecture decisions: why native development over uni-app or Taro, why Express over Koa or Nest.js, and how 40+ frontend API functions are built atop a unified request wrapper that handles token injection, 401 clearing, and error toasts automatically.

Takeaways
Five distinct tools — registration, booking, relay, entry/exit, and queue calling — share one activity table with a JSON `extra` column for tool-specific fields, avoiding table-per-type sprawl.
Activity status transitions from draft through pending_review to active, with the `ended` state detected automatically on each detail request rather than by a scheduled job.
Native WeChat Mini Program development was chosen over uni-app or Taro for zero compilation overhead, immediate new-API access, and manageable scope across 24 pages.
The backend uses Express 4.18, Sequelize 6.37, and MySQL 8.4, with JWT-based dual-role authentication using separate signing keys for admin and silent-login users.
Frontend HTTP requests are wrapped to auto-inject tokens, clear login state on 401, and show unified error toasts; 40+ semantic API functions sit on top of this layer.
Backend responses follow a uniform `{ code, msg, data/rows/total }` envelope, and a middleware converts snake_case model fields to camelCase for the frontend.
Silent login via `wx.login()` exchanges a code for openid and a JWT, so users are authenticated the moment they open the Mini Program.
Conclusions

The JSON `extra` column approach is pragmatic for a small, fixed set of tool types but would become a query and validation burden if the number of tool variants grew beyond single digits. At that point, the implicit schema inside JSON would need its own versioning.

Detecting `ended` status on read rather than via a scheduled task removes a whole class of timer-drift and missed-job bugs, but it means the status is only accurate at the moment of the next request — acceptable for an activity platform where stale `active` badges carry little risk.

Choosing native Mini Program development over a cross-platform framework is a bet that WeChat's ecosystem lock-in is worth the performance and API-access gains. The trade-off becomes painful only if the project later needs to target Alipay or Douyin Mini Programs.

Concepts & terms
Silent Login (静默登录)
A WeChat Mini Program authentication flow where `wx.login()` obtains a temporary code, the backend exchanges it for the user's openid via WeChat's API, and a JWT is returned and stored — all without any user interaction.
JSON Extension Column Pattern
A database design where a single table holds shared columns for all entity variants, and variant-specific attributes are stored in a JSON column. It avoids table proliferation at the cost of losing database-level constraints on the variant fields.
Dual-Role JWT Authentication
Issuing separate JWT tokens with different signing keys and expiry policies for two distinct user roles (e.g., admin and end-user), so a compromised end-user token cannot be escalated to admin access.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗