🚀 Full-stack mobile app for international students in Italy
CiboCompass is a full-stack mobile application designed to help users understand restaurant menus and make informed food choices across cultures.
The system combines a React Native (Expo) frontend with a Go-based backend API, supporting real-time dish information, personalized ratings, and offline-resilient rating submission.
- 📱 Cross-platform mobile app built with React Native + Expo
- ⚙️ Backend API implemented in Go with SQLite persistence
- 🌍 Cultural-aware exploration based on nationality
- 💾 Offline-resilient rating queue with local caching and idempotent delivery
- 🎯 User-centered design following HCI principles
Mobile App (React Native)
↓
REST API (Go)
↓
SQLite Database
- User searches or selects a dish in the mobile app
- App sends request to backend API
- Backend retrieves dish data from SQLite
- Response returned to mobile client
- User submits rating
- Rating stored locally and added to a durable submission queue
- Pending feedback is retried on app start or foreground events
-
Offline-resilient rating delivery
Ratings remain visible locally without network connectivity. Pending feedback is persisted inAsyncStorage, retried with the same idempotency key, and collapsed to the newest queued value for a dish/nationality pair. The current state machine documents the implemented guarantees and their limits.This is not yet full multi-device synchronization: the API has no stable actor identity or monotonic client sequence, and the backend stores aggregate counters rather than per-actor rating state. The versioned sync protocol design defines the migration required before making that claim.
-
Lightweight backend (Go)
Chosen for efficient concurrency and low overhead. -
REST API design
Stateless endpoints for scalability and easy integration. -
SQLite database
Simple and fast for development and local persistence.The backend uses one bounded
database/sqlpool with eight open and four idle connections. Foreign-key enforcement, a five-second busy timeout, and WAL journaling are applied to every physical connection. Result rows are closed before dependent ingredient queries so the read path remains safe even when the pool is constrained to one connection.This is a correctness-oriented local policy, not a published throughput claim. QPS and P99 latency will only be reported with a reproducible workload and benchmark configuration.
The implemented offline rating lifecycle is documented in
docs/offline-sync-state-diagram.md. The app
stores user ratings and pending feedback submissions locally with
AsyncStorage, then retries idempotent delivery when the app has an opportunity
to sync. Ordering across requests and devices is intentionally listed as a
non-guarantee until the versioned protocol
is implemented.
Visual files are stored with explicit names:
- docs/screenshots/cibocompass-dish-detail-screen.svg
- docs/screenshots/cibocompass-rating-country-screen.svg
- docs/demo/cibocompass-demo.gif
- Replace SQLite with PostgreSQL for scalability
- Add authentication system (JWT-based users)
- Introduce recommendation engine (collaborative filtering)
- Implement actor-scoped, versioned rating synchronization
- Deploy backend with Docker and cloud services
- Browse dishes across different countries
- Switch nationality to compare preferences
- Submit ratings per dish
- View aggregated ratings by country
- Display ingredients, calories, allergens
- Highlight vegetarian / gluten-free options
- Ratings remain visible locally after a network failure
- Pending feedback is retried on app start, foreground, or later submissions
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/dishes | Fetch dish information |
| POST | /v1/dishes | Create a dish |
| GET | /v1/dishes/:dishName | Fetch dish details for a nationality |
| POST | /v1/dishes/:dishName/feedback | Submit dish feedback |
| Layer | Technology |
|---|---|
| Frontend | React Native, Expo |
| Backend | Go (Golang), REST API |
| Database | SQLite |
| UX | HCI principles, usability testing |
git clone https://github.com/GioiaZheng/CiboCompass.git
cd CiboCompass
npm install
npm run checkCreate a local .env from .env.example, then set the backend address for the
client you are running:
| Client | EXPO_PUBLIC_API_BASE_URL |
|---|---|
| Web or iOS simulator | http://localhost:4000/v1 |
| Android emulator | http://10.0.2.2:4000/v1 |
| Physical device | http://<development-machine-LAN-IP>:4000/v1 |
For example:
EXPO_PUBLIC_API_BASE_URL=http://localhost:4000/v1EXPO_PUBLIC_ values are included in the client bundle, so this setting must
contain an endpoint only, never credentials or secrets. Reload the app after
changing it.
Start Expo:
npm run startExpected output:
Starting project at .../CiboCompass
Metro waiting on exp://...
› Press a │ open Android
› Press i │ open iOS simulator
› Press w │ open web
Backend:
cd backend
go run ./cmd/apiExpected output:
starting development server on 0.0.0.0:4000
CiboCompass/
├── assets/ # Images, icons
├── backend/ # Go API
├── App.js # Main app
├── package.json
└── README.md
Food is one of the biggest barriers for international students.
This project focuses on:
- reducing language friction in menus
- improving decision-making with structured food data
- adapting recommendations across cultural preferences
Human–Computer Interaction (HCI)
Sapienza University of Rome — 2023–2024
MIT License © 2025