Skip to content

About

Aplicación web para calcular y graficar series, integral, transformada y transformada discreta de Fourier, así como transformada de Laplace y resolver EDOs

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Repository files navigation

AEM-Lab — Advanced Engineering Mathematics Lab

A full-stack web application for symbolic computation, visualization, and interactive exploration of Fourier Series, Fourier Transforms, Laplace Transforms and ODEs. Combines a Maxima-powered mathematical engine with a modern Angular frontend featuring user authentication, calculation history, and a quota system.

Formerly known as Fourier Web Calculator / Fourier & Laplace Web Calculator.

Live: fouriersolver.com


Version License PWA Ask DeepWiki

Angular TypeScript Tailwind CSS Chart.js

Express Node.js PostgreSQL Maxima CAS


Table of Contents


Features

Mathematical computation

  • Trigonometric Fourier series (symbolic coefficients, exact closed form, Parseval identity)
  • Complex exponential Fourier series
  • Half-range series (sine and cosine expansions)
  • Continuous Fourier Transform and its inverse (multiple normalization conventions)
  • Fourier Integral (trigonometric, cosine, sine and complex forms)
  • Laplace Transform — direct, inverse and ODE solver with initial conditions
    • Free parameters (assumes positivity for symbolic ilt())
    • Partial fraction decomposition
    • Client-side LaTeX → Maxima conversion for inverse mode
  • ODE Solver (independent module) — solves 1st, 2nd and 3rd order ODEs via ode2() and characteristic polynomial method
    • General solution, IVP (initial value problem) and BVP (boundary value problem) sub-modes
    • Laplace sub-tab: wraps the Laplace ODE solver with the same UI
    • 3rd order constant-coefficient ODEs via characteristic polynomial + multiplicities for repeated roots
    • Free parameter sliders (%k1, %k2, %k3) and result canvas
  • Discrete Fourier Transform (DFT/FFT) — from points, from function samples, or from function definition
  • Expression parsing (LaTeX → Maxima), simplification, and integrability checks

Visualization

  • Real-time series reconstruction with adjustable harmonic count
  • Amplitude and phase spectrum
  • Fourier Integral graphical reconstruction (A(ω), B(ω) and f(t))
  • Laplace Transform canvas: F(s) input curve + f(t) result with parameter sliders
  • DFT epicycle animation
  • Interactive function grapher (multiple expressions, colors, zoom)
  • Coefficient tables with CSV export

User system

  • Email/password registration with email verification
  • Google OAuth sign-in
  • Password reset via email
  • JWT authentication with rotating refresh tokens
  • Weekly calculation quota (anonymous: 10 / free: 50 / premium: unlimited)
  • Calculation history with favorites, rename and filter by calculation type
  • User profile with name editing

Feedback & community

  • Post-calculation feedback modal (rating + category + message)
  • One-time demographic survey wizard (role, country, usage patterns, device, ratings)
  • Survey prompt appears automatically after the user's first calculation

Admin dashboard

  • User management (tier changes, activate/deactivate)
  • Calculation history browser with filters
  • Audit log with date/action/user filters
  • System stats (DB size, disk usage)
  • Rate limit metrics and cache inspection
  • Feedback analytics charts (by category, rating distribution, 30-day trend)
  • Survey analytics charts (role, country, how found, purpose, features, device, avg ratings, 30-day trend)

Infrastructure

  • Rate limiting per endpoint and per tier
  • LRU cache (in-memory) with optional Redis layer
  • Audit log (all auth events and calculations)
  • SEO: per-page meta tags, Open Graph, hreflang, sitemap, robots.txt
  • Google Analytics 4 (production only — zero dev pollution)
  • Multilingual UI: Spanish, English, Portuguese, German (Transloco)
  • PWA-ready (service worker, manifest)
  • SSR via Angular Universal

Tech Stack

Layer Technology Version
Frontend Angular, TypeScript, Tailwind CSS 21 / 5.9 / 4
Rendering Angular SSR (Universal), MathJax, MathQuill —
Charts Chart.js 4
i18n Transloco (ES / EN) 8
Backend Express, TypeScript, Node.js 5 / 5.9 / 20+
Math engine Maxima CAS (via shell subprocess) 5.47
Database PostgreSQL 14+
ORM / Driver pg (node-postgres) 8
Cache LRU-cache (always) + Redis (optional) 11 / 5
Auth JWT (access + refresh rotation), Google OAuth 2 —
Email Nodemailer (SMTP) 8
API docs Swagger / OpenAPI (/api-docs) —

Project Structure

Fourier-Web-Calculator/
├── fourier-backend/        # Express + TypeScript API
│   ├── src/
│   │   ├── api/
│   │   │   ├── middlewares/    # Auth, rate-limit, sanitize, validate, quota
│   │   │   └── routes/         # auth, fourier, transforms, history, admin, feedback, survey…
│   │   ├── application/
│   │   │   ├── auth/           # authService, tokenService
│   │   │   ├── fourier/        # trigonometric, complex, halfRange services
│   │   │   ├── transforms/     # fourierTransform, fourierIntegral, dft, laplace services
│   │   │   └── auxiliary/      # simplify, parse
│   │   ├── domain/
│   │   │   ├── interfaces/     # Repository contracts
│   │   │   └── types/          # Shared type definitions
│   │   ├── infrastructure/
│   │   │   ├── database/       # pg connection pool
│   │   │   ├── persistence/    # UserRepository, HistoryRepository, FeedbackRepository…
│   │   │   ├── maxima/         # maximaRunner, outputParser, scriptLoader
│   │   │   ├── cache/          # fourierCache (LRU + Redis)
│   │   │   └── email/          # emailService (Nodemailer)
│   │   └── scripts/maxima/     # .mac scripts for each calculation type
│   └── .env.example
│
├── fourier-frontend/       # Angular 21 SPA + SSR
│   ├── src/
│   │   ├── app/
│   │   │   ├── core/
│   │   │   │   ├── guards/         # auth, admin, guest, lang, dev-only
│   │   │   │   ├── interceptors/   # token injection, error handling
│   │   │   │   └── services/       # api, auth, analytics, seo, theme, feedback, survey…
│   │   │   ├── features/
│   │   │   │   ├── home/
│   │   │   │   ├── calculator/     # Fourier series (trigonometric, complex, half-range, Parseval)
│   │   │   │   ├── transforms/     # Continuous FT, Fourier Integral, DFT, Laplace
│   │   │   │   ├── ode/            # ODE solver (general / IVP / BVP / Laplace tab)
│   │   │   │   ├── grapher/        # Interactive function grapher
│   │   │   │   ├── history/        # Calculation history, favorites, type filter
│   │   │   │   ├── profile/        # User profile
│   │   │   │   ├── auth/           # Login, register, forgot/reset password
│   │   │   │   ├── feedback/       # Feedback page
│   │   │   │   ├── survey/         # Demographic survey wizard
│   │   │   │   └── admin/          # Admin dashboard + analytics charts
│   │   │   └── shared/             # Reusable components, directives, pipes
│   │   ├── assets/i18n/            # es.json, en.json
│   │   └── environments/           # environment.ts, environment.prod.ts
│   └── public/                     # sitemap.xml, robots.txt, icons
│
├── fourier-database/       # PostgreSQL schema
│   ├── fourier_db.sql              # Full schema (tables, indexes, triggers, enums)
│   ├── migrate_v2_feedback_survey.sql  # Incremental migration (dev only)
│   └── reset_db.sql                # Drop & recreate for dev
│
├── setup.sh                # First-time setup (dependencies + .env scaffold)
├── dev.sh                  # Start backend + frontend in dev mode
├── FOURIER_TABLES.md       # Database schema documentation
└── LICENSE

Requirements

  • Node.js 20+
  • npm 9+
  • Angular CLI 21+ — npm install -g @angular/cli
  • PostgreSQL 14+
  • Maxima CAS — must run on Linux (see note below)
  • Redis (optional — falls back to in-memory LRU if unavailable)

Why Linux for the backend

The backend calls Maxima as a shell subprocess. The invocation syntax and how Node.js pipes stdin/stdout differ between Linux and Windows in ways that break Maxima's output parsing. The application is designed and tested exclusively on Linux (Ubuntu/Debian). The frontend can be developed on any OS.

Installing Maxima 5.47

Ubuntu/Debian package managers ship 5.46. The application targets 5.47, which must be compiled from source:

# Dependencies
sudo apt install -y sbcl texinfo autoconf automake build-essential

# Download and compile
cd ~
wget https://sourceforge.net/projects/maxima/files/Maxima-source/5.47.0-source/maxima-5.47.0.tar.gz
tar -xzf maxima-5.47.0.tar.gz
cd maxima-5.47.0
./configure --with-sbcl
make -j$(nproc)    # takes ~10-20 min on a small VM
sudo make install
# Arch Linux
sudo pacman -S maxima

# macOS (unsupported for production, but works for local testing)
brew install maxima

Verify: maxima --version


Setup

git clone https://github.com/TheTortillas/FourierSeriesWebApp.git
cd FourierSeriesWebApp

# First-time setup: installs dependencies and scaffolds .env
./setup.sh

Environment Variables

Copy the example and fill in your values:

cp fourier-backend/.env.example fourier-backend/.env

Key variables:

# Server
PORT=3000
NODE_ENV=development

# PostgreSQL
DATABASE_URL=postgresql://user:password@localhost:5432/fourier_db

# JWT (generate strong random secrets)
JWT_ACCESS_SECRET=...
JWT_REFRESH_SECRET=...
JWT_ACCESS_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=30d

# Maxima
MAXIMA_TIMEOUT_MS=15000
MAXIMA_TRANSFORMS_TIMEOUT_MS=60000
MAXIMA_SCRIPTS_PATH=src/scripts/maxima

# Google OAuth (optional — disables Google sign-in if not set)
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...

# Email / SMTP
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=noreply@example.com
SMTP_PASS=...
SMTP_FROM=noreply@example.com

# URLs
APP_URL=http://localhost:3000
FRONTEND_URL=http://localhost:4200
FRONTEND_DEFAULT_LANG=es
ALLOWED_ORIGINS=http://localhost:4200

# Weekly calculation limits (-1 = unlimited)
CALC_LIMIT_ANONYMOUS=10
CALC_LIMIT_FREE=50
CALC_LIMIT_PREMIUM=-1

# Redis (optional)
REDIS_ENABLED=false
REDIS_URL=redis://localhost:6379

# Cache (LRU fallback — always active)
CACHE_MAX_SIZE=500
CACHE_TTL_DAYS=7

Frontend environment is configured in fourier-frontend/src/environments/:

  • environment.ts — development (GA4 disabled: ga4Id: '')
  • environment.prod.ts — production (ga4Id set, googleClientId injected by CI/CD)

Database

# Create the database
createdb fourier_db

# Apply full schema (tables, enums, triggers, indexes)
psql -d fourier_db -f fourier-database/fourier_db.sql

The schema includes:

  • persons + users — user accounts with soft-delete
  • user_auth_providers — Google OAuth linking
  • user_refresh_tokens — token rotation with family-based reuse detection
  • user_email_tokens — email verification and password reset tokens
  • calculations — canonical inputs deduplicated by SHA-256 hash
  • calculation_events — per-user/IP history, favorites, rename
  • anonymous_calculation_counters + user_calculation_counters — weekly quota with auto-reset trigger
  • audit_log — immutable event trail (auth, calculations, tier changes)
  • feedback — user feedback submissions (category, rating, message)
  • survey_responses — one-time demographic survey data (role, country, usage, ratings)

All primary keys use ULIDs via a custom gen_ulid() PostgreSQL function included in the schema.

To reset in development:

psql -d fourier_db -f fourier-database/reset_db.sql
psql -d fourier_db -f fourier-database/fourier_db.sql

Running in Development

# Single command — colored logs, pre-flight checks, clean Ctrl+C shutdown
./dev.sh

dev.sh verifies .env, node_modules, Maxima and PostgreSQL before starting. Run ./setup.sh first if you haven't.

Swagger API docs: http://localhost:3000/api-docs


API Overview

All routes are prefixed with /api.

Group Prefix Description
Auth /api/auth Register, login, Google OAuth, token refresh, email verification, password reset, profile, quota
Fourier series /api/fourier Trigonometric, complex, half-range — coefficients, first-N terms, Parseval
Transforms /api/transforms Continuous Fourier Transform, Inverse FT, Fourier Integral, DFT (points / samples / function), Laplace (direct, inverse, ODE), ODE solver (general / IVP / BVP)
Parse /api/parse LaTeX → Maxima expression parsing
Simplify /api/simplify Symbolic simplification
History /api/history CRUD for calculation history, favorites and type filter (auth required)
Feedback /api/feedback Submit user feedback (optional auth)
Survey /api/survey Submit demographic survey response (optional auth, one-time)
Admin /api/admin User management, audit log, system stats, feedback/survey analytics (admin role required)
Cache /api/cache Cache inspection and invalidation
Health /health Liveness check

Full interactive documentation: http://localhost:3000/api-docs


Architecture Notes

Maxima integration — Each calculation type has its own .mac script under fourier-backend/src/scripts/maxima/. The MaximaRunner spawns a Maxima subprocess, pipes the script via stdin, captures stdout, and the MaximaOutputParser converts the result to JSON. Results are cached by a SHA-256 hash of the input to avoid redundant computation.

Cache strategy — Two-tier: in-memory LRU (always active, configurable size/TTL) and Redis (optional). Redis is enabled via REDIS_ENABLED=true. If Redis is unavailable, the app falls back to LRU transparently.

Authentication flow — Access tokens (15 min) + rotating refresh tokens (30 days). Refresh token rotation uses family tracking to detect token reuse (replay attack prevention). Google OAuth tokens are verified server-side via google-auth-library.

Quota system — Anonymous users are tracked by IP. Authenticated users have per-account weekly counters stored in PostgreSQL. Counters reset automatically via a trigger every Monday. Limits are configurable per environment variable (CALC_LIMIT_*).

GA4 analytics — AnalyticsService injects the gtag script only when environment.ga4Id is non-empty. In development the service exits early and is a no-op, so dev traffic never contaminates analytics.

SSR — The Angular frontend uses Angular Universal for server-side rendering. Prerendered routes are defined in app.routes.server.ts. SeoService sets title, meta description, Open Graph tags, and canonical URL per route. Private pages (profile, history, auth) receive noindex, nofollow.

Feedback & Survey — Both endpoints accept optional authentication (optionalAuth middleware) so submissions can be attributed to registered users when available. The survey is stored as a single wide row per respondent; multi-select fields (purpose, features_used, device, improvements) are PostgreSQL TEXT[] columns. Admin charts use unnest() to expand array columns for GROUP BY aggregation.


Branch Strategy

Branch Purpose
main Production-ready code. Tagged releases (v13.0, v14.0, v15.0, …)
develop Integration branch — all feature branches merge here first
feat/theory-section Long-running branch for theory content and documentation pages
archive/v0-legacy Snapshot of the original v0 app (Angular 18 + plain JS backend, no auth)

Feature branches: feat/<name>. Bug fixes: fix/<name>. Always branch from develop, merge back with --no-ff.


License

Custom non-commercial license. See LICENSE. For commercial use, contact the author.

About

Aplicación web para calcular y graficar series, integral, transformada y transformada discreta de Fourier, así como transformada de Laplace y resolver EDOs

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages