basically, this project is legit cool. 😎
The Problem
Shareholder meetings (RUPS) in Indonesia traditionally required physical presence. For a company like Sinartama Gunita (Share Registrar), this meant:
- Investors flying in from across Indonesia
- Meeting venues, catering, logistics costs
- Limited participation due to travel constraints
- Slow decision-making process
Then 2020 happened and everyone realized: wait, meetings can be online right? 🤯
What is E-RUPS?
Electronic RUPS (Rapatan Umum Pemegang Saham) - basically shareholders can attend meetings, vote, and ask questions online. No more flying to Jakarta for a 30-min meeting.
The Tech Stack
Frontend:
- React + Vite (fast builds, great DX)
- WebSocket for real-time features
- Zod for validation
- Tailwind + custom UI
Backend:
- Laravel (their existing stack)
- Laravel Reverb (WebSocket server)
- PostgreSQL for data
Integrations:
- Zoom SDK (embedded meeting experience)
Key Features Built
1. Live Meeting Rooms
// Real-time participant list
const [participants, setParticipants] = useState([]);
useEffect(() => {
const ws = new WebSocket(`${WS_URL}/meeting/${meetingId}`);
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'USER_JOINED') {
setParticipants(prev => [...prev, data.user]);
}
};
return () => ws.close();
}, [meetingId]);
2. Voting System
- Real-time vote count updates
- Yes/No/Abstain options
- Animated vote bars
- Result announcement after closing
3. Q&A Module
- Participants submit questions
- Moderator approves/rejects
- Questions visible to all
- Answered during live session
4. Multi-Role Access Control
type UserRole = 'issuer' | 'investor' | 'bae' | 'intermediary';
const rolePermissions = {
issuer: ['create_meeting', 'start_voting', 'close_meeting'],
investor: ['join_meeting', 'vote', 'ask_question'],
bae: ['moderate_qna', 'view_reports'],
intermediary: ['register_attendee', 'view_attendance']
};
5. Zoom Integration
Embedded Zoom meetings within the app - participants don't need separate Zoom app. One click, you're in the meeting.
Technical Challenges
Handling 300 Concurrent Users
WebSocket connections can get heavy. solved by:
- Redis for pub/sub
- Connection pooling
- Efficient re-renders with React.memo
Data Integrity
Financial meetings need:
- Immutable vote records
- Timestamp accuracy
- Audit trail for every action
- Frontend + backend validation
Parallel Development
Worked with 3 backend devs + 2 QA. API contracts were essential. if you skip API docs in a team this size, you're gonna have a bad time. 😅
The Flow
1. Issuer creates meeting → sets agenda, date, participants
2. System sends email/SMS invites
3. Participants register → verify identity
4. Day of meeting → join via Zoom embedded SDK
5. Real-time Q&A → submit questions
6. Voting → live results
7. Meeting ends → minutes auto-generated
8. All records → audit trail complete
Results
- ✅ 300+ concurrent users supported
- ✅ Zero downtime during live meetings
- ✅ Real-time everything (voting, Q&A, chat)
- ✅ Mobile-responsive (important for older shareholders)
- ✅ Audit trail for compliance
What I Learned
- WebSocket at scale - it's different when 300 people are hitting it simultaneously
- Role-based systems - complex but essential for enterprise
- Financial data - validation is everything, trust nothing from frontend
- Integration testing - Zoom SDK + WebSocket + backend = fun times debugging 😵
this project made me realize: enterprise software doesn't have to be boring. it's actually solving real problems for real people.
Related Articles
HRIS System - Web & Mobile Application
Built an HRIS system from scratch with a scalable design system and React Native mobile app.
PAMAFix SAP - Transforming Monolith to Microservices
Revamping a monolithic ERP into microservices architecture - OTC module with dynamic forms, error handling, and .NET integration.
Music Distribution Platform - Licensing & Digital Contracts
Built a music distribution platform with payment gateway, digital signatures, and 20GB file uploads.