- 🌌 The Vision
- 🏗️ System Architecture
- 📂 Project Structure
- 🛠️ The Arsenal (Tech Stack)
- 🧩 Core Intelligence Engine
- 💳 Commerce Integration: Stripe Premium Engine
- 🛡️ The Enterprise Admin Nexus
- 🛡️ Security Hardening Roadmap (Phases 1-5)
- 🧪 Integration & E2E Testing
- 💾 Database Architecture
- 🔐 Security & Compliance
- 🚀 Local Development
- ☁️ Deployment
- � API & Server Actions
- 🤝 Contributing
- 🛣️ Roadmap
- ❓ FAQ & Troubleshooting
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.
Stratus is built on a Serverless, Edge-First Architecture designed for speed, scalability, and resilience.
- 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.
- 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.
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)We didn't just pick tools; we chose weapons. Stratus is forged with the absolute latest in web technology.
Stratus operates on a three-phase intelligence pipeline: Extract → Harmonize → Generate.
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").
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.
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.
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_idbound to the authenticated user's unique ID. This ensures the payment is tied to the intended user even if sessions are completed externally.
- Stripe Checkout sessions are created with
-
Hardened Webhook Fulfillment
- The Stripe webhook handler has been refactored to be strictly idempotent.
- A centralized
payment_historyaudit 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.
- All incoming Stripe webhook events are verified using Stripe's signature header and the configured
-
Fulfillment Guarantees
- Promotions to Plus, role assignments, and quota changes are always applied within a database transaction and recorded in
payment_historyto maintain traceability and support safe rollbacks when needed.
- Promotions to Plus, role assignments, and quota changes are always applied within a database transaction and recorded in
-
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_SECRETin your.envmatches the secret printed by the Stripe CLI.
- Use the Stripe CLI for local webhook forwarding during development:
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.
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-flashvs2.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).
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.
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.
- UseCase: During a critical DB migration, an admin toggles this switch. API routes immediately begin rejecting non-admin requests with
- 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.
- Feature: Notices support expiration times (
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 standaloneuser_rolestable. - 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
joselibrary. - 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_historytable 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_usagetable 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, andSameSite: Laxflags.
These phases are enforced by RLS, server-side checks, and automated tests that verify the new security boundaries.
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.
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.
Our End-to-End suite (powered by Playwright) is rigorous:
- The "Happy Path": Simulates a complete user journey—Landing Page -> Login -> Schedule Upload (Mock) -> Analysis -> Dashboard.
- The "Chaos Path": Simulates network failures, maintenance modes, and malformed API responses to ensure the UI handles errors gracefully.
- 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.
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.
npm run test # Run Unit & Integration Tests (Vitest)
npm run test:e2e # Run E2E Tests (Playwright)
npm run test:ui # Open Vitest UIAdditional 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.
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, anduser_usageas part of the security and commerce hardening.
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,UPDATEpolicies are strictly defined inSECURITY_RLS_POLICIES.sql.
- RLS (Row Level Security): Every query to Supabase is filtered by the standard
- 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, andSameSiteflags. - Webhook Security: All Stripe webhooks are verified using the Stripe signature verification process and the webhook secret.
- Node.js v18.x (LTS) or higher
- npm (v9+) or pnpm
- Git
- Stripe CLI (recommended for webhook testing)
-
Clone the repository:
git clone https://github.com/soroushrf/stratus.git cd stratus -
Install dependencies:
npm install # or pnpm install -
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_KEYSTRIPE_PUBLISHABLE_KEYSTRIPE_WEBHOOK_SECRET(for local dev use the Stripe CLI to obtain)JWE_PRIVATE_KEY/JWE_PUBLIC_KEY(for session encryption usingjose)
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
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 scriptTip: 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.
npm run devAccess the application at http://localhost:3000.
| 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 |
We recommend Vercel for zero-configuration deployment.
- Push your code to GitHub.
- Import the project into Vercel.
- Add your Environment Variables (copy from
.env). - 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_SECRETandSTRIPE_SECRET_KEYare set in Vercel (or your hosting provider). - Verify that webhook signing verification is active.
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 withclient_reference_idset 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_historyaudit log - Promotes users to the Plus tier exactly once per successful payment
- Logs and alerts on suspicious or failed fulfillment attempts
- Verifies the Stripe signature using
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.
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.
- Fork the repo.
- Create your feature branch (
git checkout -b feature/amazing-feature). - Commit your changes following Conventional Commits (
git commit -m 'feat: add amazing feature'). - Push to the branch.
- Open a Pull Request.
If adding features that touch commerce or security (webhooks, roles, JWE), please include integration tests and idempotent migration scripts.
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.
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/webhookCopy 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.