External Services & Integrations
Every external service KA26 depends on, why we picked it, where it shows up in the code, and which other services it talks to. Use this as the reference when:
- Onboarding a new team member
- Diagnosing "service X is down — what breaks?"
- Reviewing a vendor renewal or contract
- Considering whether to add a new dependency
Cost summary: $0/mo total ongoing. Everything is on free tiers as of 2026-04-18. The only paid line item is the Cloud Run runtime cost (~€20/mo, billed via GCP), and that's our application — not a third-party service.
☁️ Google Cloud Platform (GCP)
What it is
Our primary cloud provider. Hosts the application runtime, database, image storage, secrets, and CI/CD container builds.
Why we picked it
- Free tier generous enough for first year (Cloud Run scales to zero when idle)
- Cloud SQL (Postgres) is reliable and well-documented
- One-stop shop: compute + database + storage + secrets + DNS + monitoring all under one billing account
- Excellent CLI (
gcloud) and Terraform support for repeatability
What we use it for
| Service | Resource name | Region | Purpose |
|---|---|---|---|
| Cloud Run | ka26-marketplace | us-central1 | Hosts the Next.js 15 app (web + API) |
| Cloud SQL (Postgres 15) | school-db (legacy name) | us-central1 | Primary database, ka26 database within the instance |
| Cloud Storage | ka26-marketplace-images | us-central1 | Product/profile/reel image storage |
| Secret Manager | smtp-pass, jwt-secret, etc. | global | Server-side credentials never committed to git |
| Artifact Registry | ka26 repo | us-central1 | Container images built by Cloud Build (auto-cleanup keep 5, delete >7 days) |
| Cloud Build | (no named resource) | us-central1 | CI/CD container build path triggered by GitHub Actions |
| Cloud Logging | ka26-marketplace service logs | us-central1 | All console.log from the app, queryable in GCP console |
Configuration
- Project:
school-mgmt-saas(legacy name from a prior project — KA26 is the only active workload) - Billing account: linked to siddugkattimani@gmail.com
- Service accounts:
ka26-deployer@school-mgmt-saas.iam.gserviceaccount.com— used by GitHub Actions to deploy- Default Cloud Run runtime SA — has roles for Cloud SQL, Storage, Secret Manager
- Env vars on Cloud Run:
DATABASE_URL,JWT_SECRET,SMTP_*,EMAIL_*,SENTRY_*,VAPID_*,GCS_*,PAYMENTS_ONLINE_ENABLED,REELS_COMMERCE_ENABLED— see Feature Flags for the full list
Integrates with
- GitHub Actions — pulls deploys via
gcloud run deploy - Sentry — Cloud Run environment is tagged in every error
- Hourly health cron — pings the running service every hour
🔥 Firebase Cloud Messaging (via Expo Push)
What it is
Google's push notification service for Android. iOS uses APNs (Apple's equivalent). We use both indirectly through Expo.
Why we picked it (and Expo)
We picked Expo Push over raw Firebase because:
- One SDK for Android + iOS + web (we use the web channel via VAPID separately)
- Free, unlimited
- No
google-services.jsonto manage on multiple devices - Token rotation handled automatically
The chain: our backend → Expo Push API (https://exp.host/--/api/v2/push/send) → Firebase FCM (Android) | APNs (iOS) → device.
What we use it for
- All mobile push notifications: order updates, reel likes, comments, requests, prescriptions, doctor broadcasts.
- See Push Notifications for the full notification matrix.
Configuration
- Firebase project:
ka26-app - Android package:
com.ka26.app - FCM V1: enabled (legacy is deprecated)
- Sender ID: 640177559572
- Expo account:
siddu248(siddugkattimani@gmail.com) - Expo project ID:
d04941bf-639e-46d3-a17b-66c33446d490 - Service account JSON uploaded to Expo via
eas credentials --platform android. Seemobile/google-services.json(gitignored).
Integrates with
- Web Push (VAPID) — separate channel for browsers, dispatched by the same
pushTo*()helpers insrc/lib/push.ts - PushToken table in Postgres — every device's token is stored here with
appTypeandisActiveflags
🐛 Sentry (Error Tracking)
What it is
Real-time error monitoring for both web and mobile. Captures uncaught exceptions, unhandled promise rejections, React error boundary crashes, and slow performance traces.
Why we picked it
- Free tier (5k events/month) covers our pre-launch and early post-launch needs
- Source-map support — stack traces show TypeScript line numbers, not transpiled JS
- Native React Native SDK with crash-on-launch detection
- Issue grouping reduces alert fatigue
What we use it for
| Project | Platform | DSN location |
|---|---|---|
ka26-marketplace | Next.js (web + API routes) | Cloud Run env: SENTRY_DSN + NEXT_PUBLIC_SENTRY_DSN + SENTRY_ENV=production |
ka26-mobile | React Native | mobile/app.json → expo.extra.sentryDsn (DSNs are public IDs, safe to ship in APK) |
Configuration
- Org:
ka26on https://sentry.io - Account: siddugkattimani@gmail.com
- Source maps: web maps uploaded automatically on deploy via
next.config.tsSentry plugin (auth token inSENTRY_AUTH_TOKENGitHub secret) - Sentry SDK: v10. Worked-around gotchas:
onRequestErrorrenamed tocaptureRequestError— re-exported under old name ininstrumentation.ts- sourcemap controls nested under
sourcemapsobject — replaced top-levelhideSourceMaps
- PII scrubbing: mobile init in
mobile/app/_layout.tsxstripsevent.request?.dataandcookiesso OTPs and tokens never reach Sentry
Integrates with
- GCP Cloud Run — environment tagged on every event so we can filter by deploy
- GitHub Actions —
SENTRY_AUTH_TOKENsecret enables source-map upload on every deploy
⏰ UptimeRobot (External Synthetic Monitoring)
What it is
External pings every 5 minutes to verify our domains are responding. Independent of our infrastructure (so it catches "the whole stack is down" events that our own hourly cron would miss).
Why we picked it
- Free tier monitors 50 URLs at 5-minute intervals
- Email + SMS alerts (free tier limited; WhatsApp is paid)
- Public status page (post-launch nice-to-have at status.ka-26.com)
What we use it for
| Monitor | Type | Target | Interval |
|---|---|---|---|
| KA26 Production | HTTP(s) | https://ka26.shop/api/health | 5 min |
| KA26 Landing | HTTP(s) | https://ka-26.com | 5 min |
| KA26 SSL (shop) | SSL/TLS | ka26.shop:443 | 1 day |
| KA26 SSL (landing) | SSL/TLS | ka-26.com:443 | 1 day |
Configuration
- Account: siddugkattimani@gmail.com (free tier)
- Setup: documented in Monitoring — user setup pending as of 2026-04-18
Integrates with
- Email (siddugkattimani@gmail.com) — alerts within 2 min of outage
- GCP — independent of our stack, so it catches Cloud Run cold-start failures, DB outages, and full LB downtime
🌐 Cloudflare (DNS for ka-26.com + Docs Hosting)
What it is
Cloudflare manages DNS for ka-26.com and hosts the internal docs portal at docs.ka-26.com via Cloudflare Workers Static Assets (the new unified Pages + Workers product).
Why we picked it
- Free DNS + free SSL + free Workers Static Assets (100k requests/day, unlimited bandwidth)
- Required to host private-repo Docusaurus sites (GitHub Pages free tier requires public repos; we wanted internal docs source private)
- Built-in 2FA + audit log for security
What we use it for
| Service | Resource | Purpose |
|---|---|---|
| DNS | ka-26.com zone | Authoritative DNS for the landing domain |
| Workers Static Assets | ka26-docs | Hosts the Docusaurus internal docs portal |
| (Optional, not enabled) Cloudflare Access | — | Email-gating for docs.ka-26.com if we want to gate it later |
Configuration
- Account: siddugkattimani@gmail.com (free plan)
- Nameservers:
anahi.ns.cloudflare.com+elmo.ns.cloudflare.com - All 11 DNS records set to "DNS only" (gray cloud) — NEVER Proxied (orange cloud breaks GitHub Pages SSL, breaks SMTP, breaks DKIM)
- Workers Static Assets deploy command:
npx wrangler deploy(NOTversions upload— see Cloudflare ops doc) - 2FA enabled on the Cloudflare account (2026-04-18)
Integrates with
- GitHub (
sidgk/ka26-docsrepo, private) — Cloudflare auto-builds and deploys on every push to main - GoDaddy — NOT integrated; ka26.shop DNS is managed separately at GoDaddy
- Hostinger — was the previous DNS provider for ka-26.com; migrated away on 2026-04-17
🌐 GoDaddy (DNS for ka26.shop)
What it is
Domain registrar AND DNS host for the application domain ka26.shop.
Why we picked it
Historical — bought there originally. Has worked fine, no reason to migrate yet (DNS is simple for ka26.shop: A records to the GCP Load Balancer IP).
What we use it for
- Domain registration for
ka26.shop - DNS hosting with A records pointing to
34.8.146.193(GCP Load Balancer)
Configuration
- Account: siddugkattimani@gmail.com
- Nameservers:
ns23.domaincontrol.com+ns24.domaincontrol.com(GoDaddy defaults) - DNS records:
A @→34.8.146.193(GCP LB)A www→34.8.146.193
- (No MX records — email for ka26.shop isn't set up; Workspace email is on ka-26.com)
Integrates with
- GCP Load Balancer — currently routes traffic to Cloud Run via a forwarding rule
- (Scheduled removal) — see [TODO in MEMORY.md] — replacing the LB with Cloud Run domain mapping saves ~€18/mo. When that happens, we'll update GoDaddy DNS to point at Google's IPs directly.
🌐 Hostinger (legacy DNS for ka-26.com — no longer authoritative)
What it is
The original DNS host for ka-26.com. No longer authoritative as of 2026-04-17 — we moved to Cloudflare. Hostinger still owns the domain registration but its DNS panel is read-only for this domain now (our nameservers point at Cloudflare).
Why we moved off
- GitHub Pages free tier requires public repos
- We wanted
sidgk/ka26-docsto be private - Cloudflare Pages supports private repos for free
- Cloudflare Pages can only attach a custom domain when Cloudflare is also the authoritative DNS
Status
- ⚠️ Read-only at Hostinger as of 2026-04-17
- ⚠️ Disaster recovery: nameservers can be reverted to Hostinger if Cloudflare goes down — see Cloudflare ops doc → Disaster recovery
📧 Google Workspace (Email)
What it is
Provides the noreply@ka-26.com and other email addresses on our domain. SMTP relay for outbound mail.
Why we picked it
- Standard for any business that wants
you@yourdomain.cominstead ofyou@gmail.com - 99.9% deliverability (Gmail's reputation works in our favor)
- App Password auth for SMTP (no OAuth complexity)
- Free aliases, group emails (
grievance@ka-26.comis an alias on the support@ user)
What we use it for
- All outbound transactional email: OTP verification, password reset, order confirmation, doctor broadcasts
- All inbound mail to
support@ka-26.com,grievance@ka-26.com, etc.
Configuration
- Domain: ka-26.com
- SMTP host/port: smtp.gmail.com:465 (SSL)
- App Password (16 chars): stored in GCP Secret Manager as
smtp-pass, exposed to Cloud Run asSMTP_PASSenv var - DNS auth: SPF + DKIM + DMARC all PASS, strict alignment (
adkim=s; aspf=s). DMARC currentlyp=quarantine; will move top=reject2-4 weeks post-launch. - Library:
src/lib/email.ts— generic SMTP via nodemailer, 3-attempt retry with exp backoff - Audit log: every send logged to
EmailLogtable (Postgres) - OTP: 10-min expiry, 60s per-user resend cooldown
Integrates with
- Cloudflare DNS — SPF/DKIM/DMARC TXT records live in Cloudflare for ka-26.com
- GCP Secret Manager — SMTP password stored here; rotate via
gcloud secrets versions add smtp-pass --data-file=-
🐙 GitHub (Source Control + CI/CD)
What it is
Git hosting + GitHub Actions for CI/CD + GitHub Pages for the public landing.
Why we picked it
- Industry standard, integrates with everything
- Free for our scale (3 repos, 1 contributor)
- GitHub Actions free for public repos (we use it for the marketplace which is private but under the free monthly minute allotment)
- GitHub Pages free for public repos (used for ka-26.com landing)
What we use it for
| Repo | Visibility | Purpose | Auto-deploys to |
|---|---|---|---|
sidgk/ka26-marketplace | private | Main app source | Cloud Run via .github/workflows/deploy.yml |
sidgk/ka26-website | public | Landing page + APK download host | GitHub Pages → ka-26.com |
sidgk/ka26-docs | private (since 2026-04-17) | Internal Docusaurus portal | Cloudflare Workers Static Assets → docs.ka-26.com |
Configuration
- Account:
sidgk(siddugkattimani@gmail.com) - 2FA enabled (2026-04-18)
- Recovery codes: should be saved to 1Password (TODO if not already)
- GitHub Actions secrets:
SMTP_USER,SMTP_PASS,ALERT_TO,SENTRY_AUTH_TOKEN, plus the GCP deployer service account key
Integrates with
- GCP Cloud Run — deploys via service account JSON in GitHub secrets
- Cloudflare — Cloudflare GitHub App auto-builds the docs repo on push
- Sentry — uploads source maps via
SENTRY_AUTH_TOKENsecret
📱 Expo (Managed React Native Build Service)
What it is
The platform behind our React Native app. We use Expo's managed workflow with app.json config + EAS for credentials, but build APKs locally with gradlew.
Why we picked it
- One SDK for Android + iOS without native code
- Expo Push for notifications (vs. raw Firebase setup)
- Easy OTA updates available later (we don't use this yet)
Configuration
- Project ID:
d04941bf-639e-46d3-a17b-66c33446d490 - Owner:
siddu248 - App slug:
ka26 - SDK version: 54
Integrates with
- Firebase Cloud Messaging — Expo Push relays through FCM for Android delivery
- Sentry —
@sentry/react-nativeinitialized inmobile/app/_layout.tsx - Local APK build —
cd mobile && npx expo prebuild --platform android --clean && cd android && ./gradlew assembleRelease
💳 PhonePe (Payment Gateway — currently DISABLED)
What it is
Indian payment gateway for UPI + cards. Wired but not active until our company bank account opens.
Why we picked it
- UPI is the dominant payment method in India (Gadag's user base)
- PhonePe has good developer docs and reliable callbacks
- Reasonable commission rates
Status
- 🔴 Currently DISABLED via
PAYMENTS_ONLINE_ENABLED=falseenv var - Web + mobile hide the UPI button entirely
/api/payments/initiate*returns 503 if called/api/store-ordersrejectspaymentMethod=online- Will flip to
true2-3 weeks post-launch when bank account opens
Configuration (when enabled)
- API keys live in Cloud Run env vars (TBD when activated)
- Webhook callbacks land at
/api/payments/confirmand/api/payments/verify
Integrates with
- GCP Secret Manager — will store PhonePe API keys
- Cloud Run — handles the payment flow + webhooks
- See Feature Flags for the gating logic
🤖 Anthropic Claude (AI Coding Assistant)
What it is
Used by the engineering team during development. Not a runtime dependency — does not impact production.
Why we use it
- Pair programming, code review, documentation generation
- Has access to the codebase via MCP-style tools
- Maintains continuity via auto-loaded memory files (
bugs_fixed.md,MEMORY.mdin~/.claude/projects/)
Status
- Used by engineering only (Siddu)
- No runtime impact — purely a development tool
Summary Table — Service-by-Domain
| Service | Tier | Cost | Critical for production? |
|---|---|---|---|
| GCP Cloud Run | Pay-as-you-go | ~€20/mo | ✅ The application itself |
| GCP Cloud SQL | Pay-as-you-go (included in GCP) | ~€5/mo | ✅ Primary database |
| GCP Cloud Storage | Pay-as-you-go | under €1/mo | ✅ Image storage |
| GCP Secret Manager | Free tier | $0 | ✅ Credentials |
| Firebase / Expo Push | Free | $0 | ⚠️ Mobile push (degrades gracefully if down) |
| Sentry | Free (5k events/mo) | $0 | ⚠️ Observability (no user impact if down) |
| UptimeRobot | Free | $0 | ⚠️ External monitoring |
| Cloudflare | Free | $0 | ✅ DNS for ka-26.com + docs site |
| GoDaddy | Renewal ~€15/yr | under €2/mo | ✅ DNS for ka26.shop |
| Hostinger | Renewal ~€15/yr | under €2/mo | ⚠️ ka-26.com domain registration only |
| Google Workspace | $6/user/mo | ~€5/mo | |
| GitHub | Free (under public-repo + free private allotment) | $0 | ✅ Source + CI/CD |
| Expo | Free | $0 | ✅ Mobile app build |
| PhonePe | Per-transaction | $0 (disabled) | ⚠️ Will be critical when activated |
Total ongoing: ~€35/mo (Cloud Run + SQL + Workspace + GoDaddy/Hostinger renewals). Will save ~€18/mo when GCP Phase 3 (LB removal) lands.
Related docs
- Domains & Hosting — DNS records and hosting summary for all 3 domains
- Architecture — How these services fit together
- Monitoring & Observability — Detection + alerting setup
- Cloudflare ops — Deep dive on the DNS migration
- Email infrastructure — Deep dive on the email setup