Find available rooms at Aarhus University and view their schedules in real-time.
- Smart Room Search - Fast, intuitive search with instant results
- Geolocation-Based Recommendations - Automatically shows the 5 nearest buildings based on your location
- Favorites System - Save your frequently used rooms with localStorage persistence
- Interactive Calendar - Date picker with real-time schedule visualization
- Live Availability Status - Real-time occupied/available badges with time estimates
- Fully Responsive - Optimized for mobile, tablet, and desktop
- SEO Optimized - Danish metadata and structured data for better discoverability
- Modern UI - Clean, professional design with Tailwind CSS and shadcn/ui components
- Custom GWT-RPC Decoder - A from-scratch implementation that reverse-engineers Google Web Toolkit's RPC protocol specifically for AU's timetable API
- Handles complex serialization formats with history tracking
- Supports nested objects, arrays, and back-references
- Transforms proprietary GWT format into clean JSON
- This was the most challenging and rewarding part of the project!
- Clean Architecture - Standard Go project layout with separation of concerns
- Handlers (HTTP layer)
- Services (business logic)
- Clients (external API communication)
- Middleware (auth, logging, CORS)
- Structured JSON Logging - Production-ready logging with configurable log levels
- Bearer Token Authentication - Secure communication between frontend and backend
- State Management - Efficient room subscription tracking
- Session Management - Automatic token refresh for AU timetable API
- High Performance - Concurrent request handling with proper timeouts
- Docker Ready - Multi-stage builds for optimized containers
- Docker & Docker Compose
- OpenSSL (for generating secrets)
-
Clone the repository
git clone <your-repo-url> cd au-timetable-app
-
Generate secrets and create .env file
make setup
-
Start the application
make run
-
Access the application
- Frontend: http://localhost:5080
- Backend API: http://localhost:8080
make stop # Stop all containers
make logs # View container logs
make http # Run backend locally (without Docker)
make test # Run testsmake httpmake http-devmake testmake build.
├── backend/
│ ├── cmd/
│ │ ├── api/ # API server entry point
│ │ └── decode/ # CLI tool for decoding GWT-RPC payloads
│ ├── internal/
│ │ ├── handler/ # HTTP handlers
│ │ ├── service/ # Business logic
│ │ ├── client/ # External API clients
│ │ ├── middleware/ # Auth, logging, etc.
│ │ ├── config/ # Configuration management
│ │ └── state/ # Application state
│ ├── pkg/
│ │ ├── gwtrpc/ # GWT-RPC protocol implementation ⭐
│ │ │ ├── decoder/ # Custom decoder (the pride and joy!)
│ │ │ ├── encoder/ # Request encoder
│ │ │ └── parser/ # Response parser
│ │ └── logger/ # Structured JSON logging
│ └── testdata/ # Test fixtures
├── frontend/
│ ├── app/
│ │ ├── schedule/[roomId]/ # Room detail pages
│ │ └── api/ # API proxy routes
│ ├── components/ # Reusable React components
│ └── lib/ # Utilities and helpers
├── .env.example # Environment variables template
├── docker-compose.yml
└── Makefile
The crown jewel of this project is the custom GWT-RPC decoder (backend/pkg/gwtrpc/decoder/). GWT-RPC is a proprietary serialization protocol used by Google Web Toolkit, and there are no existing Go implementations.
What makes it special:
- Reverse Engineered Protocol - Built by analyzing network traffic and GWT source code
- Complex Type Handling - Manages nested objects, arrays, maps, and custom types
- History Tracking - Implements GWT's object reference system for deduplication
- Back-Reference Resolution - Handles circular references and object reuse
- Production Tested - Processes real AU timetable data with 100% accuracy
Example usage:
decoder := decoder.NewDecoder(payloadBuffer)
result, err := decoder.Decode()
// Transforms GWT binary format into structured Go dataYou can even use it as a standalone CLI tool:
make decode payload.txtCreated by Mikkel Maae Østergaard
Not affiliated with Aarhus Universitet