Skip to content

SoroushRF/Stratus

Repository files navigation

Stratus Logo

🌥️ S T R A T U S

AI-Powered Weather & Attire Intelligence

Next.js React TypeScript Supabase Auth0 Stripe Gemini AI Tests CI Build License

Building the future of personal preparation through intelligent context.



📖 Table of Contents


🌌 The Vision

We live in an era of information overload. Students and professionals juggle fragmented data every morning: a PDF class schedule, a weather app showing "average" city temperatures, and a wardrobe full of unorganized clothes.

Stratus turns this chaos into order.

It is not just a weather app. It is a Context Engine. By understanding exactly where you need to be and when, Stratus acts as a hyper-intelligent layer between your calendar and the atmosphere. It eliminates the cognitive load of preparation, answering the only question that matters: "What should I wear to survive today?"

As Stratus evolves, it also helps users manage premium features (like higher API quotas and personalized Concierge recommendations) via a robust subscription model integrated with Stripe. The platform ensures subscription attribution integrity and secure fulfillment so that paid benefits (Plus tier) are provisioned reliably and auditably.


🏗️ System Architecture

Stratus is built on a Serverless, Edge-First Architecture designed for speed, scalability, and resilience.

Frontend Layer (The Experience)

  • Next.js 15 (App Router): Utilizing React Server Components (RSC) to minimize client-side bundle size while delivering dynamic, interactive UI.
  • Micro-Interactions: Powered by framer-motion, every hover, transition, and loading state is choreographed to feel fluid and premium.
  • Glassmorphism Design System: A custom Tailwind CSS implementation that uses backdrop-blur, variable transparency, and noise textures to create a deep, modern aesthetic.

Backend Layer (The Intelligence)

  • Server Actions: We bypass traditional API routes for direct, type-safe mutations from the client to the database/AI services.
  • Edge Routing: Critical logic runs close to the user, ensuring sub-100ms latency for initial renders.
  • Supabase (BaaS): Managed PostgreSQL provides robust relational data storage with Row Level Security (RLS) policies baked into the schema.
  • Subscription & Fulfillment: Stripe Checkout sessions and idempotent webhook fulfillment run in dedicated serverless handlers to ensure Plus-tier entitlements are applied exactly once and securely.

📂 Project Structure

A high-level overview of the most critical directories and files in our hardened architecture.

/
├── config/                 # Tool configurations (moved from root)
│   ├── vitest.config.ts    # Unit/Integration test setup
│   └── playwright.config.ts # E2E test setup
├── docs/                   # Architecture decision records & security plans
│   ├── architecture.md     # 10,000ft view of system design & ERD
│   └── security/           # Hardening roadmaps & audit logs
├── scripts/                # Utility scripts (e.g., verifying RLS)
├── src/
│   ├── app/                # Next.js App Router (Routes & Pages)
│   │   ├── api/            # Serverless API Endpoints (Stripe, Auth, Data)
│   │   ├── actions.ts      # Server Actions (Type-safe mutations)
│   │   └── admin/          # "God Mode" dashboard routes
│   ├── components/         # React Components
│   │   ├── ui/             # Reusable design primitives (Buttons, Cards)
│   │   └── dashboard/      # Complex widget logic
│   ├── lib/                # Core Business Logic & Singletons
│   │   ├── auth/           # JWE Encryption & Auth0 helpers
│   │   ├── services/       # External Integrations (Gemini, Tomorrow.io)
│   │   ├── middleware/     # Security checks (ensureUser, rateLimit)
│   │   └── stripe.ts       # Stripe SDK initialization
│   ├── types/              # TypeScript definitions
│   └── __tests__/          # The Quality Assurance Lab
│       ├── unit/           # Business logic verification
│       ├── integration/    # API & Database interaction tests
│       └── e2e/            # Full browser automation (Playwright)
├── supabase/
│   └── migrations/         # Idempotent SQL schemas (RLS, Tables, Triggers)
├── next.config.ts          # Next.js framework config
├── package.json            # Dependencies & Scripts
└── middleware.ts           # Global Request Interception (Auth checks)

🛠️ The Arsenal (Tech Stack)

We didn't just pick tools; we chose weapons. Stratus is forged with the absolute latest in web technology.

Frontend Velocity Intelligence Core Ironclad Infra

🧩 Core Intelligence Engine

Stratus operates on a three-phase intelligence pipeline: Extract → Harmonize → Generate.

1. AI-Driven Schedule Extraction (Gemini 2.5 Flash Lite)

Traditional OCR is brittle. Stratus uses Multimodal LLMs to "see" your schedule like a human does.

  • Visual Parsing: Upload a blurry photo or a complex PDF grid. The model identifies days, times, and locations based on visual layout, not just text scraping.
  • Fuzzy Logic Correction: It inferentially corrects typos (e.g., "MTH 101" -> "Math 101") and resolves partial time formats (e.g., "2-4" -> "14:00 - 16:00").

2. Temporal Weather Harmonization (Tomorrow.io)

City-wide forecasts are useless for a student walking across a 500-acre campus.

  • Geospatial Precision: We map every supported university campus to exact latitude/longitude coordinates.
  • Temporal Slicing: We fetch 24-hour hourly forecasts including temperature, wind chill ("RealFeel"), humidity, and precipitation probability.
  • The Matching Algorithm: Our custom algorithm iterates through your parsed classes and "locks in" the weather conditions specifically for your commute times.

3. Generative Attire Reasoning (Context-Aware LLM)

This is the "Brain" of Stratus. It doesn't just output "Wear a coat."

  • Layering Strategy: It analyzes the delta between your coldest outdoor walk and your heated lecture hall. If the variance is >15°F, it suggests removable layers.
  • Master Recommendation: It synthesizes the entire day's volatility into a single "Strategy" to minimize decision fatigue.

💳 Commerce Integration: Stripe Premium Engine

Stratus now includes a first-class commerce layer to manage Plus-tier subscriptions and attribution integrity. This section documents the implemented subscription model and fulfillment guarantees.

  • Subscription Model

    • We support a "Plus" tier via Stripe Checkout that grants users premium features such as increased Gemini/Tomorrow.io quotas and priority recommendations.
    • Checkout sessions use immutable identity binding (see below) to prevent payment attribution errors.
  • Immutable Identity Binding

    • Stripe Checkout sessions are created with client_reference_id bound to the authenticated user's unique ID. This ensures the payment is tied to the intended user even if sessions are completed externally.
  • Hardened Webhook Fulfillment

    • The Stripe webhook handler has been refactored to be strictly idempotent.
    • A centralized payment_history audit log is used to ensure that a user is promoted to the "Plus" tier exactly once per successful payment, even if Stripe retries events.
  • Signature Verification

    • All incoming Stripe webhook events are verified using Stripe's signature header and the configured STRIPE_WEBHOOK_SECRET. Events failing verification are rejected and logged.
  • Fulfillment Guarantees

    • Promotions to Plus, role assignments, and quota changes are always applied within a database transaction and recorded in payment_history to maintain traceability and support safe rollbacks when needed.
  • Dev & Testing Notes

    • Use the Stripe CLI for local webhook forwarding during development:
      • stripe listen --forward-to http://localhost:3000/api/stripe/webhook
    • Ensure the STRIPE_WEBHOOK_SECRET in your .env matches the secret printed by the Stripe CLI.

🛡️ The Enterprise Admin Nexus

The Admin Nexus is not an afterthought; it is a first-class citizen of the Stratus ecosystem. Designed for Engineering Leads and System Operators, it provides "God Mode" capabilities over every facet of the application.

It is secured by a double-verification layer (Auth0 Role Check + Supabase Database Verification) ensuring that even if one layer is compromised, administrative functions remain secure.

Technological Governance

The admin panel provides deep insights into the AI performance and API consumption:

  • Token Telemetry: A real-time dashboard visualizing Gemini API usage. It breaks down input vs. output tokens, calculating an estimated daily burn rate to prevent cost overruns.
  • Model Efficiency Tracking: Administrators can audit latency distribution across different Gemini models (1.5-flash vs 2.0-flash-exp) to make data-driven decisions on which model to deploy for production.
  • System Health Monitor: A live pulse of external dependencies (Supabase, Auth0, Tomorrow.io).

User & Data Sovereignty

From the /admin/users and /admin/universities routes, admins possess granular control:

  • RBAC Management: Instantly promote or demote users to Administrator status.
  • University Asset Management: A CRUD interface for managing the global university database. Admins can update campus coordinates, adjusting the specific "Weather Center Point" for thousands of students instantly.
  • User Lifecycle Control: The ability to inspect user profiles, debug sync issues, and ban bad actors from the platform.

Operations Command Center

The /admin/operations route is the mission control for site reliability:

  • Emergency Maintenance Mode: A "Kill Switch" that instantly locks the frontend.
    • UseCase: During a critical DB migration, an admin toggles this switch. API routes immediately begin rejecting non-admin requests with 503 Service Unavailable, and the UI renders a beautiful, informative Maintenance Screen to end-users.
  • Global Broadcast System: A notification engine allowing admins to push "System Notices" (Info, Warning, Critical) to all connected clients.
    • Feature: Notices support expiration times (expires_at), ensuring that "System Degradation" alerts automatically disappear once the incident window passes.

🛡️ Security Hardening Roadmap (Phases 1-5)

To meet enterprise production standards, Stratus underwent a comprehensive 5-phase security overhaul. These phases are now part of the baseline architecture and testing.

Phase 1: Identity-Role Segregation

  • Architecture: Segregated sensitive user privileges (is_admin, is_premium) into a standalone user_roles table.
  • Access Control: Locked the roles table behind the service_role, making it inaccessible to standard authenticated users and preventing "Privilege Scaling" attacks.

Phase 2: Session Encryption & JWE

  • Encryption: Transitioned from plain JSON session cookies to encrypted JWE (JSON Web Encryption) using the jose library.
  • Security: Session payloads are now unreadable and untamperable on the client side, significantly mitigating cookie-based session hijacking.

Phase 3: Fulfillment & Audit Logging

  • Traceability: Created a centralized payment_history table to log all financial events.
  • Idempotency: Automated the fulfillment process to be resistant to duplicate webhook events, protecting the system from redundant database writes.

Phase 4: Resource Rate Limiting

  • Target: Protected expensive AI (Gemini) and Weather (Tomorrow.io) API budgets from "Wallet Draining" attacks.
  • Logic: Implemented a per-user daily quota system that tracks usage in a user_usage table and enforces tier-aware limits (Free vs. Plus) in real-time.

Phase 5: CSRF Defense & Origin Verification

  • Enforcement: Enhanced all Server Actions with mandatory Origin and Host Verification.
  • Mitigation: The system now automatically rejects any cross-site request that tries to trigger actions on behalf of a user from a mismatched origin.
  • Cookie Hardening: Standardized session cookies with HttpOnly, Secure, and SameSite: Lax flags.

These phases are enforced by RLS, server-side checks, and automated tests that verify the new security boundaries.


🧪 Integration & E2E Testing

Reliability is a feature. At Stratus, we treat our test suite as the supreme source of truth. We have integrated a full CI/CD Dashboard directly into the application at /admin/tests.

Testing Philosophy

We employ a "Testing Trophy" strategy, heavily emphasizing Integration and E2E tests over brittle unit tests.

  • Realism over Mocking: Whenever possible, we test against real data structures. When we do mock, we use Network Interception (via Playwright) rather than fragile implementation-detail mocking.
  • Strict Mode Compliance: Our UI tests enforce accessibility. We do not select elements by CSS classes (which change). We select by Role and Label, ensuring our app remains usable for screen readers.

The E2E Testing Pipeline

Our End-to-End suite (powered by Playwright) is rigorous:

  1. The "Happy Path": Simulates a complete user journey—Landing Page -> Login -> Schedule Upload (Mock) -> Analysis -> Dashboard.
  2. The "Chaos Path": Simulates network failures, maintenance modes, and malformed API responses to ensure the UI handles errors gracefully.
  3. Visual Regression: Every pixel is accounted for. The tests verify that the "Layering Strategy" text appears exactly where expected, with the correct casing and visibility.

Metric: 108 Tests Passing

As of the latest build, Stratus boasts a 100% Green status across 108 distinct tests:

  • 103 Unit/Integration Tests: Validating complex date math, weather data parsing, API routes, and Stripe Webhook Fulfillment (Signature verification, Idempotency, and Audit logging).
  • 5 Critical E2E Flows: Covering the entire application surface area from landing page to dashboard.
  • Parametrized Cases: Ensuring edge cases (Leap years, midnight classes, empty schedules) are handled deterministically.

This suite is runnable directly from the Admin Dashboard, streaming logs via Server-Sent Events (SSE) so non-technical stakeholders can verify system health.

Run Tests Locally

npm run test        # Run Unit & Integration Tests (Vitest)
npm run test:e2e    # Run E2E Tests (Playwright)
npm run test:ui     # Open Vitest UI

Additional QA & Resilience Notes:

  • Idempotent Migrations: All database schema changes are delivered as idempotent SQL scripts, ensuring safe and repeatable deployments across environments.
  • Hardened Integration Tests: The test suite has been updated to reflect the security hardening (roles, JWE sessions, webhook idempotency). Integration tests validate that API routes and Server Actions enforce the new security boundaries and that webhook fulfillment is idempotent.

� Database Architecture

Our Supabase (PostgreSQL) schema relies on a user-centric relational model.

Table Description Key Fields
users Core profile linked to Auth0 ID id (PK), email, university_id, onboarding_completed
schedules Parsed daily schedules id (PK), user_id (FK), raw_content (Text/JSON), is_active
universities Geo-spatial campus data id (PK), name, latitude, longitude, timezone
notices System-wide broadcasts id (PK), message, type (info/crit), is_active
admin_audit Security logs for admin actions id, admin_id, action, resource, timestamp
user_roles Segregated role assignments id, user_id (FK), role (admin/premium), granted_by, granted_at
payment_history Financial audit log for Stripe & payments id, user_id, stripe_event_id, stripe_payment_intent, amount, currency, status, processed_at
user_usage API usage / quota tracking id, user_id, date, gemini_calls, tomorrow_calls, quota_limit

See docs/architecture.md for the full Entity-Relationship Diagram (ERD). Note: the ERD has been updated to include user_roles, payment_history, and user_usage as part of the security and commerce hardening.


�🔐 Security & Compliance

Stratus handles sensitive user data (location habits, schedules). We treat security as paramount.

  • Authentication: Auth0 handles identity management (OIDC compliant). We never touch passwords.
  • Database Security:
    • RLS (Row Level Security): Every query to Supabase is filtered by the standard auth.uid() policy plus custom security definers. A user physically cannot fetch another user's schedule.
    • Policy Enforcement: SELECT, INSERT, UPDATE policies are strictly defined in SECURITY_RLS_POLICIES.sql.
  • Environment Isolation: API Keys (Gemini, Tomorrow.io, Stripe) are kept server-side. The client never sees a raw API token.
  • Session Security: Sessions are encrypted using JWE (see Security Hardening Roadmap Phase 2), and cookies are hardened with HttpOnly, Secure, and SameSite flags.
  • Webhook Security: All Stripe webhooks are verified using the Stripe signature verification process and the webhook secret.

🚀 Local Development

Prerequisites

  • Node.js v18.x (LTS) or higher
  • npm (v9+) or pnpm
  • Git
  • Stripe CLI (recommended for webhook testing)

Environment Setup

  1. Clone the repository:

    git clone https://github.com/soroushrf/stratus.git
    cd stratus
  2. Install dependencies:

    npm install
    # or
    pnpm install
  3. Configure Environment: Copy the example file and fill in your secrets.

    cp .env.example .env

    Note: You will need API keys for Google Gemini, Tomorrow.io, Stripe, and a Supabase instance URL/Key. See Getting API Keys below.

    Required additional env variables for commerce & security:

    • STRIPE_SECRET_KEY
    • STRIPE_PUBLISHABLE_KEY
    • STRIPE_WEBHOOK_SECRET (for local dev use the Stripe CLI to obtain)
    • JWE_PRIVATE_KEY / JWE_PUBLIC_KEY (for session encryption using jose)

    Example Stripe CLI usage for local webhooks:

    stripe login
    stripe listen --forward-to http://localhost:3000/api/stripe/webhook
    # copy the webhook secret printed by the CLI into STRIPE_WEBHOOK_SECRET

Database Seeding

To spin up a local admin user or standard test user:

# (Placeholder script) - Use Supabase Dashboard for now or run:
# npm run seed
# TODO: Implement local seed script

Tip: To create an admin, manually update the is_admin flag in your local Supabase users table row.
Tip: To create a premium/Plus user for integration tests, insert a user_roles row with role='premium' and create a corresponding payment_history entry for auditability.

Running the App

npm run dev

Access the application at http://localhost:3000.

Quick Commands Table

Command Description
npm run dev Start local dev server with Hot Module Replacement
npm run build Compile for production (Next.js build)
npm run start Start production server
npm run lint Run ESLint check
npm run test Execute Vitest unit suite
npm run test:e2e Execute Playwright E2E suite

☁️ Deployment

We recommend Vercel for zero-configuration deployment.

  1. Push your code to GitHub.
  2. Import the project into Vercel.
  3. Add your Environment Variables (copy from .env).
  4. Edge Functions: Ensure your Supabase region is geographically close to your Vercel Function Region (e.g., us-east-1) to minimize latency.

Self-hosting: You can build a Docker container using the standard Next.js Dockerfile pattern, but you will lose Edge Function capabilities unless you use a compatible runtime.

Operational notes for Stripe in production:

  • Configure the Stripe webhook endpoint in the Stripe Dashboard to point to your production URL /api/stripe/webhook.
  • Ensure the STRIPE_WEBHOOK_SECRET and STRIPE_SECRET_KEY are set in Vercel (or your hosting provider).
  • Verify that webhook signing verification is active.

🔌 API & Server Actions

Stratus uses Server Actions (src/app/actions.ts) for 90% of data mutations. This ensures type safety and eliminates the need for a separate API layer documentation for internal features.

Public Endpoints:

  • POST /api/auth/hooks: Webhook for Auth0 Post-Registration (syncs user to Supabase).
  • GET /api/cron/weather-cache: (Protected) Revalidates campus weather data.
  • POST /api/stripe/checkout-session: (Protected) Creates a Stripe Checkout session with client_reference_id set to the authenticated user's ID.
  • POST /api/stripe/webhook: (Public) Stripe webhook receiver that:
    • Verifies the Stripe signature using STRIPE_WEBHOOK_SECRET
    • Idempotently processes events against the payment_history audit log
    • Promotes users to the Plus tier exactly once per successful payment
    • Logs and alerts on suspicious or failed fulfillment attempts

Server Actions now include mandatory Origin and Host verification and will reject requests from mismatched origins. All payment fulfillment is performed server-side and recorded in payment_history.


🤝 Contributing

We welcome contributions to the stratosphere! Please read our CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.

  1. Fork the repo.
  2. Create your feature branch (git checkout -b feature/amazing-feature).
  3. Commit your changes following Conventional Commits (git commit -m 'feat: add amazing feature').
  4. Push to the branch.
  5. Open a Pull Request.

If adding features that touch commerce or security (webhooks, roles, JWE), please include integration tests and idempotent migration scripts.


🛣️ Roadmap

Stratus is evolving. Here is our flight path for the next fiscal quarter:

  • Phase 1: Foundation: Architecture setup, Next.js 15 integration.
  • Phase 2: The Eye: Multimodal Schedule Extraction (PDF/Image).
  • Phase 3: The Atmosphere: Tomorrow.io API integration with localized weather.
  • Phase 4: The Brain: Generative Styling Logic & Context Engine.
  • Phase 5: Identity: User Accounts, Cloud Profiles (Supabase + Auth0).
  • Phase 6: Polish: Experience refinement, Micro-interactions.
  • Phase 7: Social: "Outfit Checks", Social Sharing, Style History.
  • Phase 8: Omnipresence: Native Mobile Wrapper (Capacitor/React Native).

Planned commerce & security enhancements:

  • Expand subscription plans and billing cycles in Stripe.
  • Add admin tooling to manually reconcile payments and re-run fulfillment for failed events.
  • Ongoing security reviews and penetration testing.

❓ FAQ & Troubleshooting

Q: My "Mock Mode" tests are failing? A: Ensure MOCK_AI=true is set in your test environment. Check src/lib/services/attire.ts for the "Magic String" triggers.

Q: How do I get an Admin Account? A: After logging in via Auth0, manually go to your Supabase users table and set is_admin = true for your UUID.

Q: I'm getting Auth0 redirect errors locally. A: Ensure your AUTH0_BASE_URL is set to http://localhost:3000 and that this URL is whitelisted in your Auth0 Application settings.

Q: How do I test Stripe webhooks locally? A: Use the Stripe CLI to forward webhooks to your local server:

stripe listen --forward-to http://localhost:3000/api/stripe/webhook

Copy the CLI-provided webhook secret into STRIPE_WEBHOOK_SECRET in your .env.

Q: What happens if Stripe sends duplicate webhook events? A: The webhook handler is idempotent and uses the payment_history audit log to ensure each effective payment is fulfilled exactly once.


Stratus is open-source software licensed under the MIT License.

Crafted with obsession by Soroush and the Stratus Engineering Team.

About

This app makes sure you don't get wet unintentionally.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors