Basmati is a full-stack calendar platform for teams and communities that need one place to organize events, calendars, comments, notifications, and external imports.
Calendar data is often fragmented between providers, personal tools, and team-specific workflows. Basmati centralizes that information behind one frontend and one API entry point, while keeping backend responsibilities split into focused services.
- Hierarchical calendars (parent/child structure) with inherited visibility and recursive event loading.
- Multi-view calendar UI (year, month, week, day) optimized for dense event timelines.
- Event details with comments, location rendering, and attachment support.
- Integrated authentication flow with Google OAuth plus development-user mode for local testing.
- Cross-service integrations for Google Calendar, Teamup, OpenStreetMap geocoding, and S3 image uploads.
- API Gateway that proxies versioned endpoints and aggregates OpenAPI docs from backend services.
flowchart LR
UI[Frontend - React/Vite] --> GW[API Gateway :8000]
GW --> US[User Service :8001]
GW --> CS[Calendar Service :8002]
GW --> ES[Event Service :8003]
GW --> NS[Notification Service :8004]
GW --> AS[Auth Service :8005]
GW --> IS[Integration Service :8006]
US --> DB[(MongoDB)]
CS --> DB
ES --> DB
NS --> DB
IS --> DB
IS --> GOOGLE[Google Calendar API]
IS --> TEAMUP[Teamup API]
IS --> OSM[OpenStreetMap/Nominatim]
IS --> S3[AWS S3]
| Service | Port | Responsibility |
|---|---|---|
api-gateway |
8000 | Single entry point, proxy routing, OpenAPI aggregation |
user-service |
8001 | User profiles and preferences |
calendar-service |
8002 | Calendar CRUD and hierarchy |
event-service |
8003 | Event lifecycle, comments, attachments |
notification-service |
8004 | Notification feed and unread state |
auth-service |
8005 | OAuth flow and JWT issuance |
integration-service |
8006 | External provider imports, maps, media uploads |
| Layer | Technologies |
|---|---|
| Frontend | React 18, TypeScript, Vite, Tailwind CSS, Axios |
| Backend | FastAPI, Python 3.11, httpx, pydantic v2 |
| Data | MongoDB Atlas, Motor, PyMongo |
| Auth | Google OAuth, JWT |
| Integrations | Google Calendar, Teamup, OpenStreetMap, AWS S3, SendGrid |
| Infra | Docker, Docker Compose, Nginx, GitHub Actions |
- Docker + Docker Compose
- A MongoDB connection string
- Node.js 18+ (only if running frontend outside Docker)
git clone https://github.com/arrozet/basmati.git
cd basmati/appUse the following as a minimal starting point:
MONGO_URI=mongodb+srv://<user>:<password>@<cluster>/<db>
VITE_API_GATEWAY_URL=http://localhost:8000
FRONTEND_URL=http://localhost:5173
JWT_SECRET_KEY=change-this-in-real-environments
CORS_ORIGINS=http://localhost:5173
ENVIRONMENT=development
# Optional integrations
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_CALENDAR_API_KEY=
TEAMUP_API_KEY=
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_REGION=
AWS_S3_BUCKET_NAME=
SENDGRID_API_KEY=docker compose up --build- Frontend:
http://localhost:5173 - API docs (Gateway):
http://localhost:8000/docs - OpenAPI JSON:
http://localhost:8000/openapi.json
The frontend calendar pages consume events through a dedicated hook:
const { events, loading, refresh } = use_calendar_events(
current_date,
view,
calendar_id,
hidden_calendar_ids,
current_user_id
);cd app/frontend
npm install
npm run devpython -m pip install -r app/backend/requirements-all.txt
pip install pytest
PYTHONPATH=app/backend pytest app/backend/testsProduction deployment scripts and operational notes are available in:
deployment/README.mddeployment/deploy.shdeployment/setup-ec2.shdeployment/monitor.sh
The current deployment target is AWS EC2 with Nginx as reverse proxy and Docker Compose for service orchestration.
.
├── .github/
│ └── workflows/
│ └── deploy.yml
├── app/
│ ├── backend/
│ │ ├── api-gateway/
│ │ ├── auth_service/
│ │ ├── calendar_service/
│ │ ├── event_service/
│ │ ├── integration_service/
│ │ ├── notification_service/
│ │ ├── shared/
│ │ ├── tests/
│ │ └── user_service/
│ ├── database/
│ ├── docker-compose.yml
│ └── frontend/
│ ├── public/
│ ├── src/
│ │ ├── application/
│ │ ├── domain/
│ │ ├── infrastructure/
│ │ └── presentation/
│ ├── Dockerfile
│ ├── package.json
│ ├── tailwind.config.js
│ └── vite.config.ts
├── deployment/
├── docs/
├── LICENSE
└── README.md
- Expand test coverage beyond smoke/config checks with service-level integration tests.
- Add real-time notifications (WebSockets or Server-Sent Events).
- Improve recurrence editing and conflict handling UX.
- Introduce stronger authorization controls for private and shared calendars.
Contributions are welcome. For non-trivial changes, open an issue first so we can align on scope and implementation approach.
Typical flow:
- Fork the repository.
- Create a branch (
feature/...orfix/...). - Keep changes focused and documented.
- Run tests.
- Open a pull request with context and screenshots when UI is affected.
This project is licensed under GPL-3.0. See LICENSE for details.

