Track time. Mark milestones. Grow in God.
Overview • Features • Getting Started • Architecture • CybUrban Studio • Contributing
"So teach us to number our days, that we may apply our hearts unto wisdom."
— Psalm 90:12
Number Our Days (NOD) is a health & wellness dashboard for the inner man; aimed at Christians who want to live intentionally and track their walk with God. It helps you visualize time's passage - indirectly prompting you to purposefully live it out, record meaningful moments, maintain a prayer journal, and reflect on God's Scripture daily.
CybUrban Studio is NOD's integrated rendering engine that transforms city maps into minimalist art pieces embedded with God's Word. It's a way to see God's presence across the globe through beautiful, shareable posters!
Time is going... but are you? Go purposefully and with intention with the Number Our Days app!
- No pressure, only invitation: Notifications are gentle reminders, never guilt trips
- Privacy first: No one can see your journal entries, Barbara. AES-256 encryption.
- Faith-focused design: Built specifically for any Christian who wants wellness the Christ-pointing way.
- Beautiful interfaces: iOS-inspired design with smooth animations
- Global accessibility: PPP-based pricing makes CybUrban Studio affordable worldwide. You're welcome!
Track the passage of time with precision and beauty:
- Real-time progress rings for year, month, week, and day
- Decimal precision up to 6 places for accurate awareness
- Smooth circular animations that respond to time's flow
- Home screen widgets for quick glances
Record and reflect on significant moments:
- Track baptisms, salvations, church memberships, ministry moments
- Custom categories for personal, family, health, and educational milestones
- Countdown and count-up views with visual progress (COMING SOON)
- Priority levels and smart reminder systems (COMING SOON)
- Attach photos and detailed notes to each milestone (COMING SOON)
Engage with God's Word daily:
- Daily verse notifications at times you choose
- Save verses with personal notes and context
- Spaced repetition memory system for scripture memorization (COMING SOON)
- Deep linking to YouVersion, Logos, and Olive Tree Bible apps
- Beautiful verse cards ready for sharing (courtesy of Cyburban Studios)
Organize and track your prayer life:
- Categorized prayer lists for different needs
- Prayer journal
- Answered prayer tracker to record testimonies
- Flexible reminders (daily, weekly, custom schedules) (COMING SOON)
- Prayer streak tracking with grace periods for rest
Process life's moments thoughtfully:
- Gratitude journal with mood tracking
- Meditation prompts tied to time progress
- Testimony and confession logs
- Link reflections to specific milestones
- Export journals to PDF for safekeeping
Generate beautiful reminders of God's workmanship from city maps:
- High-resolution map posters for any city worldwide
- Multiple aesthetic themes (noir, blueprint, sunset, etc.)
- Embed scripture verses into your posters
- PPP-adjusted pricing based on your country
- 5-stage rendering pipeline you can watch in real-time
- Device-specific mockup previews & presets (iPhone, 4K display, print-ready)
Get reminders that adapt to you:
- Three pressure levels: Gentle, Moderate, Active
- Smart scheduling based on your behavior patterns
- Respects quiet hours and do-not-disturb settings
- Contextual prompts (reflect now, save this verse) (COMING SOON)
Your spiritual journey is deeply personal:
- Local-first storage with database sync once online
- Optional encrypted cloud backup via Supabase (COMING SOON)
- Biometric lock and PIN protection (COMING SOON)
- No tracking, no ads, no data selling
- Full GDPR compliance with export and delete options
- Framework: React with Vite and TypeScript
- Styling: Tailwind CSS with Shadcn UI components
- Animation: Framer Motion for smooth transitions
- Charts: Recharts for analytics dashboard
- Icons: Material You as the source
- Database: Supabase (PostgreSQL with Row-Level Security)
- Edge Functions: Supabase Edge Functions (Deno runtime)
- Compute: Railway for Python rendering workers
- Storage: Supabase Buckets for renders and logs, Backblaze for future Renders (COMING SOON)
- Email: Resend for transactional notifications & Brevo for SMTP with Supabase email automations on Auth
- Geospatial: OSMnx for OpenStreetMap data
- Graphics: Matplotlib and PIL for image synthesis
- Acceleration: Vulkan pipeline for GPU rendering
- Language: Kotlin
- UI: Jetpack Compose with Material Design 3
- Architecture: Clean Architecture (MVVM + Repository pattern)
- Database: Room SQLite with Flow-based reactive queries
- Background Work: WorkManager for scheduling
- Widgets: Glance for Compose
graph TD
A[Client: React SPA] --> B{Supabase Auth & DB}
B -->|Trigger Render| C[Railway: Python Worker]
C -->|Fetch Streets| D[OpenStreetMap API]
C -->|Render| E[Rendering Engine]
E -->|Upload| F[Supabase Storage]
F -->|Signal Complete| G[Supabase Edge Function]
G -->|Notify User| A
G -->|Admin Alert| H[Admin Dashboard]
- User Action: User creates milestone, prayer, or render request
- Authentication: Supabase Auth validates user identity
- Database Write: Data persists to PostgreSQL with RLS enforcement
- Background Jobs: Railway workers process render requests
- Storage: Completed renders upload to Supabase Buckets
- Notifications: Edge Functions trigger emails and in-app updates
- Real-time Updates: Frontend receives updates via Supabase subscriptions
nod_v004/
├── app-frontend/ # React + Vite frontend
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ ├── pages/ # Page-level components
│ │ ├── hooks/ # Custom React hooks
│ │ ├── services/ # API clients and services
│ │ ├── stores/ # State management
│ │ └── utils/ # Helper functions
│ ├── public/ # Static assets
│ └── vite.config.ts # Vite configuration
│
├── cyburban-renderer/ # Python rendering service
│ ├── main.py # Worker entry point
│ ├── render_engine/ # Core rendering logic
│ ├── themes/ # Map theme definitions
│ └── requirements.txt # Python dependencies
│
├── supabase/ # Backend logic and schema
│ ├── migrations/ # Database schema migrations
│ ├── functions/ # Edge Functions (Deno)
│ └── seed.sql # Initial data seeding
│
├── mobile-android/ # Android app (Kotlin)
│ ├── app/src/main/
│ │ ├── java/com/nod/ # Kotlin source files
│ │ └── res/ # Resources
│ └── build.gradle.kts
│
└── docs/ # Documentation
- Node.js v18 or higher
- Python 3.10 or higher
- Supabase CLI (installation guide)
- Railway CLI (installation guide)
- Git
For Android development:
- Android Studio Hedgehog (2023.1.1) or later
- JDK 17
- Android SDK 34 (minimum SDK 26)
git clone https://github.com/|GITHUB_USERNAME|/nod_v004.git
cd nod_v004Create your environment file:
cp .env.template .envEdit .env and fill in the required values. See the Environment Variables section below for details.
Initialize Supabase and run migrations:
# Start local Supabase (optional for local development)
supabase start
# Push migrations to your Supabase project
supabase db pushIf you prefer using the Supabase Dashboard:
- Log in to Supabase
- Navigate to SQL Editor
- Run the migration files from
supabase/migrations/in order
Set up the rendering service:
cd cyburban-renderer
# Create virtual environment
python -m venv .venv
# Activate it (on macOS/Linux)
source .venv/bin/activate
# On Windows
# .venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Test the renderer
python main.py --testInstall and run the frontend:
cd app-frontend
# Install dependencies
npm install
# Start development server
npm run devThe app should now be running at http://localhost:5173.
To build the Android app:
- Open the
mobile-android/directory in Android Studio - Sync Gradle dependencies
- Create
local.propertieswith your API keys:
supabase.url=YOUR_SUPABASE_URL
supabase.anon.key=YOUR_SUPABASE_ANON_KEY- Build and run on emulator or device
Create a .env file in the project root with these variables:
# Supabase Configuration
VITE_SUPABASE_URL=|SUPABASE_URL|
VITE_SUPABASE_ANON_KEY=|SUPABASE_ANON_KEY|
SUPABASE_SERVICE_ROLE_KEY=|SUPABASE_SERVICE_ROLE_KEY|
# Railway Configuration
RAILWAY_PROJECT_ID=|RAILWAY_PROJECT_ID|
RAILWAY_RENDER_URL=|RAILWAY_RENDER_URL|
# Email Service (Resend)
RESEND_API_KEY=|RESEND_API_KEY|
# Error Tracking (Optional)
SENTRY_DSN=|SENTRY_DSN|
# External APIs
BIBLE_API_KEY=|BIBLE_API_KEY|
# Rendering Configuration
RENDER_STORAGE_BUCKET=cyburban-renders
RENDER_TMP_PATH=/tmp/cyburban
VULKAN_ENABLED=true
# App Configuration
APP_ENV=development
APP_DEBUG=trueSupabase Keys:
- Dashboard → Project Settings → API
VITE_SUPABASE_URL: Your project URLVITE_SUPABASE_ANON_KEY: The anon/public keySUPABASE_SERVICE_ROLE_KEY: Service role key (keep this secret)
Railway:
- Railway Dashboard → Your Project → Service → Variables
- Copy the service URL and project ID
Resend API Key:
- Sign up at resend.com
- Create an API key in the dashboard
Sentry DSN (optional):
- Create a project at sentry.io
- Copy the DSN from Project Settings → Client Keys
Bible API Key:
- Register with your chosen Bible API provider
- Most services offer free tiers for development
profiles
CREATE TABLE profiles (
id UUID PRIMARY KEY REFERENCES auth.users(id),
email TEXT UNIQUE NOT NULL,
display_name TEXT,
is_admin BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);milestones
CREATE TABLE milestones (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES profiles(id) ON DELETE CASCADE,
title TEXT NOT NULL,
description TEXT,
category TEXT NOT NULL,
milestone_date TIMESTAMPTZ NOT NULL,
priority INTEGER DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT NOW()
);prayers
CREATE TABLE prayers (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES profiles(id) ON DELETE CASCADE,
content TEXT NOT NULL,
category TEXT,
is_answered BOOLEAN DEFAULT false,
answered_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);cyburban_transactions
CREATE TABLE cyburban_transactions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES profiles(id) ON DELETE CASCADE,
status TEXT NOT NULL CHECK (status IN ('pending', 'rendering', 'completed', 'failed')),
city TEXT NOT NULL,
country TEXT,
theme TEXT NOT NULL,
verse TEXT,
amount NUMERIC,
render_url TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);All tables implement Row-Level Security (RLS) policies:
- Users can only read/write their own data
- Admin users have elevated permissions for all tables
- Service role bypasses RLS for backend operations
Example policy for milestones:
CREATE POLICY "Users can view own milestones"
ON milestones FOR SELECT
USING (auth.uid() = user_id);
CREATE POLICY "Users can insert own milestones"
ON milestones FOR INSERT
WITH CHECK (auth.uid() = user_id);CybUrban Studio is the rendering engine that creates minimalist map posters embedded with scripture.
- Global Coverage: Render any city with OpenStreetMap data
- Multiple Themes: 17+ aesthetic presets (noir, blueprint, sunset, etc.)
- Scripture Integration: Embed verses directly into your posters
- High Resolution: Device-specific exports up to 4K
- Fair Pricing: PPP-adjusted costs based on your country/region
- Live Progress: Watch your render progress through 5 stages
- Request: User selects city, theme, and verse
- Accepted: Transaction created in database
- Synthesizing: Python worker fetches map data from OSM
- Rendering: Graphics engine creates the poster
- Uploading: Completed render uploads to storage
- Handover: User receives download link and notification
POST /api/render
- Initiates a new render job
- Requires authentication
- Body:
{ city, country, theme, verse, preset } - Returns:
{ transactionId, status }
GET /api/render/:id/status
- Check render progress
- Returns:
{ status, progress, renderUrl }
GET /api/health
- Worker health check
- Returns:
{ status, queueSize, workersActive }
Hidden Access (Easter Egg)
For users who discover it, CybUrban Studio has hidden UI triggers from the NOD App interface:
Unlock Studio Access:
- Location: Home Tab, NOD Logo
- Action: Tap logo 3 times within 2 seconds
- Result: CybUrban Studio button appears in Verse of the Day card
Admin Dashboard Access:
- Requirement: User must have authorization from backend
- Action: Tap logo 5 times within 3 seconds
- Result: Admin interaction initiates
Note: These are UI features only. Authorization is still enforced server-side.
The renderer supports these map themes:
noir- Black background with white roadsblueprint- Architectural blueprint stylesunset- Warm oranges and pinksmidnight_blue- Navy with gold accentsjapanese_ink- Minimalist ink washterracotta- Mediterranean warmthforest- Deep greens and sageocean- Blues and tealspastel_dream- Soft muted colorsneon_cyberpunk- Dark with electric pink/cyanwarm_beige- Vintage sepia tonesemerald- Lush dark greencopper_patina- Oxidized copper aestheticautumn- Burnt oranges and redsmonochrome_blue- Single blue color familygradient_roads- Smooth gradient shadingcontrast_zones- High contrast urban density
Pre-configured output sizes for common devices:
- Instagram Post: 1080 x 1080px
- Mobile Wallpaper: 1080 x 1920px
- iPhone 15 Pro: 1179 x 2556px
- MacBook Pro: 3024 x 1964px
- 4K Display: 3840 x 2160px
- Print Ready (A4): 2480 x 3508px (300 DPI)
- Build the frontend:
cd app-frontend
npm run build- Deploy to Vercel:
vercel deploy --prodOr connect your GitHub repo in the Vercel dashboard for automatic deployments.
- Link your service:
cd cyburban-renderer
railway link- Deploy:
railway upOr enable automatic deployments from GitHub in the Railway dashboard.
- Create a new project at supabase.com
- Run migrations:
supabase db push- Deploy Edge Functions:
supabase functions deploy notify-admin- Configure storage buckets in the Supabase dashboard
- Set up Row-Level Security policies (included in migrations)
The project uses GitHub Actions for continuous integration.
Frontend CI (.github/workflows/frontend.yml):
- Runs on every push and pull request
- Lints code with ESLint
- Type-checks with TypeScript
- Runs unit tests
- Builds production bundle
Renderer CI (.github/workflows/renderer.yml):
- Python linting with flake8
- Unit tests with pytest
- Integration tests with OSM fixtures
Deployment:
- Merges to
maintrigger automatic deploys - Railway for Python workers
- Vercel/Netlify for frontend
- Supabase Edge Functions deploy via CLI
cd app-frontend
# Run unit tests
npm test
# Run with coverage
npm run test:coverage
# Run e2e tests (if configured)
npm run test:e2ecd cyburban-renderer
# Activate virtual environment
source .venv/bin/activate
# Run tests
pytest
# Run with coverage
pytest --cov=render_engine --cov-report=htmlcd mobile-android
# Unit tests
./gradlew test
# Instrumented tests (requires emulator/device)
./gradlew connectedAndroidTestCreate a new migration:
supabase migration new migration_nameApply migrations:
supabase db pushRollback last migration:
supabase db resetBackup Supabase Database:
pg_dump -h db.PROJECT_REF.supabase.co -U postgres -d postgres > backup.sqlRestore:
psql -h db.PROJECT_REF.supabase.co -U postgres -d postgres < backup.sqlRotate service role keys periodically:
- Generate new key in Supabase Dashboard
- Update Railway environment variables
- Update local
.envfiles - Restart all services
- Revoke old key after confirming everything works
Frontend won't start:
- Clear
node_modulesand reinstall:rm -rf node_modules && npm install - Check Node version:
node --version(should be v18+) - Verify environment variables are set
Renderer fails:
- Check Python version:
python --version(should be 3.10+) - Verify Vulkan drivers if using GPU acceleration
- Check Railway logs for error details
- Ensure OpenStreetMap API is accessible
Database connection issues:
- Verify Supabase URL and keys in
.env - Check if your IP is whitelisted in Supabase dashboard
- Confirm database is running:
supabase status
- Local-first architecture: All user data stored locally by default
- Encrypted storage: Sensitive data encrypted at rest
- End-to-end encryption: Prayer journal entries encrypted client-side
- Secure transmission: All API calls over HTTPS with certificate pinning
- Granular permissions: Users control what syncs to cloud
- Data export: Full data export in JSON format anytime
- Right to deletion: Complete account and data deletion on request
- No tracking: No analytics without explicit opt-in
- No ads: Free and ad-free forever
- Supabase Auth: Industry-standard authentication
- OAuth support: Google, Apple sign-in available
- MFA ready: Two-factor authentication supported
- Biometric lock: Fingerprint/Face ID on mobile
- GDPR compliant: Full data portability and deletion
- No third-party sharing: Your data is never sold or shared
- Transparent policies: Clear privacy policy and terms of service
- ✅ Time progress tracking with visual rings
- ✅ Milestone management
- ✅ Prayer journal with answered prayer tracking
- ✅ Daily verse notifications
- ✅ CybUrban Studio rendering engine
- ✅ Admin dashboard
- ✅ Android app
- ✅ Home screen widgets
- iOS app (Swift + SwiftUI)
- Spaced repetition verse memorization
- Bible reading plan integration
- Enhanced prayer circle features
- Desktop companion app (Electron)
- Advanced analytics dashboard
- Family accounts with shared milestones
- Church group features
- Devotional content library
- AI-powered reflection prompts
- Apple Watch and Wear OS apps
- Multi-language support
We welcome contributions from the community! Whether you're fixing bugs, adding features, or improving documentation, your help is appreciated.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
TypeScript/JavaScript:
- Use ESLint and Prettier configurations
- Follow React best practices
- Write meaningful variable names
- Add JSDoc comments for complex functions
Python:
- Follow PEP 8 style guide
- Use Black for formatting
- Add type hints
- Write docstrings for functions
Kotlin (Android):
- Follow Kotlin coding conventions
- Use KDoc comments for public APIs
- Run
ktlintFormatbefore committing
- Maintain at least 80% code coverage
- Add tests for new features
- Ensure all tests pass before submitting PR
- Include integration tests where applicable
- Translations: Spanish, Portuguese, Korean, Chinese, French
- UI/UX improvements: Design suggestions and mockups
- Performance optimizations: Speed improvements
- Documentation: Tutorials, guides, video walkthroughs
- Accessibility: Screen reader support, keyboard navigation
- Testing: More test coverage, edge cases
- GitHub Issues: Report bugs or request features
- GitHub Discussions: Ask questions and share ideas
- Email: |EMAIL|
This project is licensed under the MIT License. See the LICENSE file for details.
- Biblical foundation: Psalm 90:12
- OpenStreetMap community: For providing global map data
- OSMnx: For powerful geospatial analysis tools
- Supabase team: For the amazing backend platform
- Framer Motion: For beautiful animations
- All contributors: Thank you for making NOD better
If you find NOD helpful, consider:
- ⭐ Starring the repository
- 🐛 Reporting bugs and suggesting features
- 📢 Sharing with your community
- 🙏 Praying for the project and its users
- 💻 Contributing code or documentation
Built with care and intention.
For the glory of God and the furtherance of His Kingdom.
Made with ❤️ by Sam Gatana
Email • GitHub • Twitter • Tiktok • Instagram
```android
kotlin
jetpack-compose
material-design
christianity
faith
prayer
bible
spiritual-growth
time-tracking
milestone-tracking
journal
productivity
clean-architecture
room-database
mvvm
supabase
widgets
notifications
privacy-focused
Number Our Days: A faith-focused Android app for tracking spiritual milestones and time progress. Built with Jetpack Compose and Material Design 3.
