Add lessons module, rate cycles, EC2 deploy scripts, and help content

- Lessons module: lesson types, instructors, schedule slots, enrollments,
  sessions (list + week grid view), lesson plans, grading scales, templates
- Rate cycles: replace monthly_rate with billing_interval + billing_unit on
  enrollments; add weekly/monthly/quarterly rate presets to lesson types and
  schedule slots with auto-fill on enrollment form
- Member detail page: tabbed layout for details, identity documents, enrollments
- Sessions week view: custom 7-column grid replacing react-big-calendar
- Music store seed: instructors, lesson types, slots, enrollments, sessions,
  grading scale, lesson plan template
- Scrollbar styling: themed to match sidebar/app palette
- deploy/: EC2 setup and redeploy scripts, nginx config, systemd service
- Help: add Lessons category (overview, types, instructors, slots, enrollments,
  sessions, plans/grading); collapsible sidebar with independent scroll;
  remove POS/accounting references from docs
This commit is contained in:
Ryan Moon
2026-03-30 18:52:57 -05:00
parent 7680a73d88
commit 5ad27bc196
47 changed files with 6303 additions and 139 deletions

27
deploy/deploy.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
# LunarFront — Redeploy script (run after pushing changes to main)
# Usage: sudo bash deploy/deploy.sh
set -euo pipefail
APP_DIR="/opt/lunarfront"
APP_USER="ubuntu"
BUN_BIN="/home/${APP_USER}/.bun/bin/bun"
cd "$APP_DIR"
echo "==> Installing dependencies..."
sudo -u "$APP_USER" "$BUN_BIN" install --frozen-lockfile
echo "==> Building admin frontend..."
sudo -u "$APP_USER" bash -c "cd ${APP_DIR}/packages/admin && ${BUN_BIN} run build"
echo "==> Running migrations..."
sudo -u "$APP_USER" bash -c \
"cd ${APP_DIR}/packages/backend && ${BUN_BIN} x drizzle-kit migrate"
echo "==> Restarting backend..."
systemctl restart lunarfront
echo "==> Done! Checking status..."
sleep 2
systemctl status lunarfront --no-pager

18
deploy/lunarfront.service Normal file
View File

@@ -0,0 +1,18 @@
[Unit]
Description=LunarFront API Server
After=network.target postgresql.service
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/opt/lunarfront/packages/backend
EnvironmentFile=/opt/lunarfront/.env
ExecStart=/home/ubuntu/.bun/bin/bun run src/main.ts
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=lunarfront
[Install]
WantedBy=multi-user.target

47
deploy/nginx.conf Normal file
View File

@@ -0,0 +1,47 @@
server {
listen 80;
server_name YOUR_DOMAIN www.YOUR_DOMAIN;
# Certbot will automatically add HTTPS redirect and SSL config below this line
root /opt/lunarfront/packages/admin/dist;
index index.html;
# Proxy API requests to Bun backend
location /v1/ {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60s;
client_max_body_size 20M;
}
# WebDAV passthrough (all HTTP methods)
location /webdav/ {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 120s;
client_max_body_size 100M;
}
# SPA fallback — serve index.html for all unmatched paths
location / {
try_files $uri $uri/ /index.html;
}
# Cache hashed static assets aggressively
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
gzip on;
gzip_vary on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml;
}

128
deploy/setup.sh Executable file
View File

@@ -0,0 +1,128 @@
#!/usr/bin/env bash
# LunarFront — One-time EC2 provisioning script
# Run as root (or with sudo) on a fresh Ubuntu 24.04 instance.
# Usage: sudo bash deploy/setup.sh
set -euo pipefail
REPO_URL="git@github.com:YOUR_ORG/YOUR_REPO.git"
APP_DIR="/opt/lunarfront"
APP_USER="ubuntu"
DB_USER="lunarfront"
DB_NAME="lunarfront"
DB_PASS="$(openssl rand -hex 16)" # auto-generated; written to .env
# ── 1. System packages ────────────────────────────────────────────────────────
echo "==> Updating system packages..."
apt-get update -y && apt-get upgrade -y
apt-get install -y curl git build-essential nginx certbot python3-certbot-nginx unzip
# ── 2. Bun runtime ────────────────────────────────────────────────────────────
echo "==> Installing Bun..."
sudo -u "$APP_USER" bash -c 'curl -fsSL https://bun.sh/install | bash'
BUN_BIN="/home/${APP_USER}/.bun/bin/bun"
# ── 3. PostgreSQL 16 ──────────────────────────────────────────────────────────
echo "==> Installing PostgreSQL 16..."
apt-get install -y postgresql-16 postgresql-contrib-16
systemctl enable --now postgresql
echo "==> Creating database user and database..."
sudo -u postgres psql -tc "SELECT 1 FROM pg_roles WHERE rolname='${DB_USER}'" | grep -q 1 || \
sudo -u postgres psql -c "CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASS}';"
sudo -u postgres psql -tc "SELECT 1 FROM pg_database WHERE datname='${DB_NAME}'" | grep -q 1 || \
sudo -u postgres psql -c "CREATE DATABASE ${DB_NAME} OWNER ${DB_USER};"
# ── 4. Valkey 8 ───────────────────────────────────────────────────────────────
echo "==> Installing Valkey..."
# Try official Valkey apt repo first; fall back to Redis 7 if unavailable
if curl -fsSL https://packages.valkey.io/ubuntu/gpg.asc 2>/dev/null | \
gpg --dearmor -o /usr/share/keyrings/valkey.gpg; then
echo "deb [signed-by=/usr/share/keyrings/valkey.gpg] https://packages.valkey.io/ubuntu noble main" \
> /etc/apt/sources.list.d/valkey.list
apt-get update -y && apt-get install -y valkey
REDIS_SERVICE="valkey"
else
echo "Valkey repo unavailable, falling back to Redis 7..."
apt-get install -y redis-server
REDIS_SERVICE="redis-server"
fi
systemctl enable --now "$REDIS_SERVICE"
# ── 5. Clone repository ───────────────────────────────────────────────────────
echo "==> Cloning repository to ${APP_DIR}..."
if [ -d "$APP_DIR" ]; then
echo " ${APP_DIR} already exists, skipping clone."
else
git clone "$REPO_URL" "$APP_DIR"
chown -R "$APP_USER:$APP_USER" "$APP_DIR"
fi
cd "$APP_DIR"
# ── 6. Environment file ───────────────────────────────────────────────────────
if [ ! -f "${APP_DIR}/.env" ]; then
echo "==> Generating .env..."
JWT_SECRET=$(openssl rand -hex 32)
cat > "${APP_DIR}/.env" <<EOF
DATABASE_URL=postgresql://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}
REDIS_URL=redis://localhost:6379
JWT_SECRET=${JWT_SECRET}
PORT=8000
HOST=0.0.0.0
NODE_ENV=production
CORS_ORIGINS=http://$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4)
STORAGE_LOCAL_PATH=${APP_DIR}/data/files
EOF
chown "$APP_USER:$APP_USER" "${APP_DIR}/.env"
chmod 600 "${APP_DIR}/.env"
echo " Generated JWT secret and wrote .env"
echo " NOTE: Update CORS_ORIGINS once you have a domain."
else
echo " .env already exists, skipping generation."
fi
# ── 7. Install dependencies + build frontend ──────────────────────────────────
echo "==> Installing dependencies..."
sudo -u "$APP_USER" "$BUN_BIN" install --frozen-lockfile
echo "==> Building admin frontend..."
sudo -u "$APP_USER" bash -c "cd ${APP_DIR}/packages/admin && ${BUN_BIN} run build"
# ── 8. Run database migrations ────────────────────────────────────────────────
echo "==> Running database migrations..."
sudo -u "$APP_USER" bash -c \
"cd ${APP_DIR}/packages/backend && ${BUN_BIN} x drizzle-kit migrate"
# ── 9. Create file storage directory ─────────────────────────────────────────
mkdir -p "${APP_DIR}/data/files"
chown -R "$APP_USER:$APP_USER" "${APP_DIR}/data"
# ── 10. Systemd service ───────────────────────────────────────────────────────
echo "==> Installing systemd service..."
# Substitute real Bun path into service file
sed "s|/home/ubuntu/.bun/bin/bun|${BUN_BIN}|g" \
"${APP_DIR}/deploy/lunarfront.service" > /etc/systemd/system/lunarfront.service
systemctl daemon-reload
systemctl enable lunarfront
systemctl restart lunarfront
# ── 11. Nginx ─────────────────────────────────────────────────────────────────
echo "==> Configuring Nginx..."
cp "${APP_DIR}/deploy/nginx.conf" /etc/nginx/sites-available/lunarfront
ln -sf /etc/nginx/sites-available/lunarfront /etc/nginx/sites-enabled/lunarfront
rm -f /etc/nginx/sites-enabled/default
nginx -t && systemctl reload nginx
echo ""
echo "========================================================"
echo " Setup complete!"
echo ""
echo " Next steps:"
echo " 1. Verify .env has correct values:"
echo " nano ${APP_DIR}/.env"
echo " 2. Restart backend after editing .env:"
echo " sudo systemctl restart lunarfront"
echo " 3. Set up HTTPS (after pointing DNS to this IP):"
echo " sudo certbot --nginx -d YOUR_DOMAIN -d www.YOUR_DOMAIN"
echo " 4. Check logs:"
echo " journalctl -u lunarfront -f"
echo "========================================================"