Found a student card on the third floor of the library — DM me
Anonymous · 3 min ago
Four surfaces live · mini program / web / console / server
Submissions queued in someone's DMs, sign-ups by group-chat roll call, headcounts in a spreadsheet, and when something goes wrong all you can do is delete a message. That isn't a lack of effort — it's the wrong tool. WeSmile ships the whole set: student verification, content distribution, an anonymous tree hole, event sign-ups, a marketplace, course reviews, weekly matchmaking, and an admin console a campus moderator can run without a developer.
Written for student unions, clubs, and the people running a campus wall.
Found a student card on the third floor of the library — DM me
Anonymous · 3 min ago
Full set of grad-school prep books, barely used, pickup on campus
¥120 · School of Computing
Friday 7pm · club recruitment info session
128 / 200 signed up
Light on homework, brutal on the final
Grading 4.2 · Teaching 4.8
Tonight's sunset is worth looking up for
❤ 246 · whole school
Found a student card on the third floor of the library — DM me
Anonymous · 3 min ago
Full set of grad-school prep books, barely used, pickup on campus
¥120 · School of Computing
Friday 7pm · club recruitment info session
128 / 200 signed up
Light on homework, brutal on the final
Grading 4.2 · Teaching 4.8
Tonight's sunset is worth looking up for
❤ 246 · whole school
Matched — say hi
37th pair this week
Is that monitor still available?
Delivered live
Student status confirmed · via school email
Took 1m 12s
A post was taken down; the author got the reason
Handled in 4 min
12-day check-in streak
+30 points
main bundle + 7 sub-bundles
student-facing and console APIs
one account, one corpus
email / photo / quiz
Why change the approach
None of them are solved by trying harder — there's simply no structure holding the work.
Submissions pile up in DMs; every repost is laid out by hand
A structured feed where publishing means persisting: topic, images, place and engagement are fields, not screenshots
"Are you actually a student here?" runs on the honour system
Email, student card photo or a school-specific quiz — and the result decides what someone can post and who they can message
All you can do is delete a message, block someone, post an announcement — and by tomorrow nobody remembers why
A report queue, content review and graded restrictions, each step recorded, with the rejection reason handed back verbatim
Sign-ups by roll call, attendee lists as screenshots, totals in a spreadsheet
Sessions, sign-ups and an attendee roster — it was structured data before anyone exported it
The full picture
Not a checklist of features — each one is built far enough to hand to real students.
The campus feed: topics, six browsing ranges, likes and saves, threaded comments.
Real anonymity: the author is a persona, and the client never receives an internal id.
Start to finish: sessions, sign-ups, attendee roster, a timeline, and comments.
Second-hand goods on campus. Post, search, view, message the seller.
Rate the grading and the teaching separately. Reviews are anonymous.
A questionnaire, a human pairing it, contact details exchanged. No algorithm, on purpose.
Live over WebSocket, with a quota, blocking, recall and three privacy levels.
Three routes: a school email, a student card photo, or a campus quiz.
In-app points. Earned by checking in, topped up, spent, and fully itemised.
Browse clubs, apply to join, wear a club title — with admins scoped to exactly one club.
Carousels, placements, a daily poem, the shortcut grid, homepage tabs — all configurable.
Four target types × five reasons, up to six pieces of evidence. Deletes are soft and reversible.
Real screens
All captured from a running build — not mockups, and not retouched. The names, posts and numbers are demo data: the interface is real, the people are invented.
Write, attach, publish, watch it land in the feed — choosing which club identity to post as, and whether to spend points pinning it.
How it works
From tapping publish to being taken down, these seven steps are identical on all four surfaces — because all seven live on the server.
The client never decides for itself; it asks the server what it's allowed to do
Account, verification and restriction status resolved in one pass, with a reason attached
Text and images pass content safety; what fails is never persisted
A post sits at its author's campus and school; readers decide how far out to look
Likes, saves, shares and threaded comments; counts are batched, not queried per row
Four target types, five reasons, up to six attachments; a duplicate report counts as success
Unpublish or soft-delete, both reversible; the reason goes back to the author verbatim
Keeping the rules on the server means changing one of them changes all four surfaces at once — it's the only way they stay in sync for longer than a semester.
Four surfaces
Students use the mini program or the browser; operators change something in the console and all four surfaces follow.
Native mini-program framework · 88 screens
Where students actually live. Hot screens in the main bundle, eight sub-bundles split by domain.
Next.js 16 · shadcn/ui · 36 routes
The mini program's 88 screens collapse into 36 routes, organised by capability rather than by page.
Next.js 16 · roles × scopes
Built for campus staff. Review, placements, quiz banks, matchmaking and orders all live here.
Spring Boot 4 · JPA · Redis · MySQL 8
Nineteen business domains sliced vertically: changing the tree hole means opening one directory.
Governance
A community's lifespan is decided on its worst day
The client asks once — "what can I do right now?" — and gets back a list of names: post, comment, message, join, match. It never derives a rule like "unverified, therefore can't post". Derived rules fork into four different versions on four surfaces.
Super admins, operators, moderators, campus admins and club admins each get a surface area. Anything outside your scope returns "not found" — identical to genuinely not existing. Otherwise the error message alone would let you probe what another school has.
Whatever the server says when it refuses has to be shown. Rejection reasons are free text written by a moderator, and the student really does read them — so whatever goes in that box is what goes back to a person.
Alternatives
Group chats and public accounts aren't bad. They were simply never designed for this.
Verified student identity
Content is searchable
Graded browsing range
Anonymous and named side by side
Sign-ups with a roster
Operations console
You hold the data
| Group chat | Public account wall | Generic community SaaS | WeSmile | |
|---|---|---|---|---|
| Verified student identity | No | No | No | Yesthree routes |
| Content is searchable | No | Sort of | Yes | Yestopics + search |
| Graded browsing range | No | No | Sort of | Yessix, nearest outward |
| Anonymous and named side by side | No | Sort of | No | Yestree-hole personas |
| Sign-ups with a roster | No | No | Sort of | Yessession-based |
| Operations console | No | Sort of | Yes | Yescampus / club level |
| You hold the data | No | No | No | Yesself-hosted |
A few answers up front
Getting listed
This question has a real name inside the system: a school onboarding request. It isn't an email to us — it's a counter you can watch, in the app.
Typing a school name shows you candidates first: "did you mean one of these?" That step isn't a courtesy. Once a name splinters into "MIT / Massachusetts Institute of Technology / MIT (main campus)", none of the three ever reaches the threshold and the whole feature may as well not exist. The server also normalises names into one counting key, and the console can merge branches that already split.
After submitting you see how many people have asked for this school and how many are still needed. One vote per person. You can withdraw it; when the last person leaves, the empty counter goes with them rather than lingering as a row that reads "0 people waiting".
Nobody has to click approve. The threshold defaults to 200 people and ships down with every record — the client only displays it, never computes it, so the gap you read on screen is the same number the server judges by.
A school created by threshold lands in "pending open": it still needs campuses and region codes, a home logo, and a decision on which verification methods it offers plus whatever they depend on — quiz verification means writing a question bank first. Until those are done it doesn't appear in the school picker.

Scan this with WeChat to open the trial build — no app install, no sign-up first.
This code is valid until 2026-09-12
Applicants don't get a "your school is live" message when the school is created, because at that point it isn't usable. The opening notice waits until it actually opens, and it is sent exactly once. Better a late notice than a promise that can't be honoured that day.
The system is self-hosted by design: code, database and object storage all sit with you. A school can stand up its own instance — no queue, no headcount. That path is in the launch playbook, and its first step is cutting features.
Read the playbookThe feature tour answers "what's in it". The playbook answers "where do I begin".
1142704468@qq.comWeChat