158 Commits

Author SHA1 Message Date
Matt
0d7ac4b1de Add missing logger.info() and logger.debug() methods
All checks were successful
Build and Push Docker Images / docker (push) Successful in 43s
FIX: TypeError: z.info is not a function in production

The logger object was missing .info() and .debug() methods that were
being called in OffsetOrder.tsx and other components. This caused
checkout to fail in production with "z.info is not a function" error.

Added:
- logger.info() - Info level logging (dev only)
- logger.debug() - Debug level logging (dev only)

All logger methods now follow the same pattern:
- log, info, warn, debug: Only log in development
- error: Always log (production + development)

🔒 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 12:34:07 +01:00
Matt
04bfef4391 Fix frontend runtime environment configuration
All checks were successful
Build and Push Docker Images / docker (push) Successful in 46s
CRITICAL FIX:
- Frontend now loads environment variables at runtime instead of build time
- This allows changing configuration without rebuilding the Docker image

CHANGES:
- Add env-config.js script loader to index.html
- Update env.sh to use correct path for serve (/app/dist)
- Update Dockerfile to run env.sh before starting serve
- Add VITE_STRIPE_PUBLISHABLE_KEY to docker-compose environment

HOW IT WORKS:
1. env.sh reads VITE_* variables from container environment
2. Generates /app/dist/env-config.js with window.env object
3. index.html loads env-config.js before React app
4. src/utils/config.ts reads from window.env at runtime

This fixes the "Missing required environment variable: WREN_API_TOKEN" error
because the frontend can now access environment variables passed to the container.

🔒 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 12:30:29 +01:00
Matt
bc9e2d3782 Implement comprehensive Stripe security fixes and production deployment
All checks were successful
Build and Push Docker Images / docker (push) Successful in 1m22s
CRITICAL SECURITY FIXES:
- Add webhook secret validation to prevent signature bypass
- Implement idempotency protection across all webhook handlers
- Add atomic database updates to prevent race conditions
- Improve CORS security with origin validation and logging
- Remove .env from git tracking to protect secrets

STRIPE INTEGRATION:
- Add support for checkout.session.expired webhook event
- Add Stripe publishable key to environment configuration
- Fix webhook handlers with proper idempotency checks
- Update Order model with atomic updatePaymentAndStatus method
- Add comprehensive logging for webhook processing

DEPLOYMENT ARCHITECTURE:
- Split into two Docker images (frontend-latest, backend-latest)
- Update CI/CD to build separate frontend and backend images
- Configure backend on port 3801 (internal 3001)
- Add production-ready docker-compose.yml
- Remove redundant docker-compose.portainer.yml
- Update nginx configuration for both frontend and backend

DOCUMENTATION:
- Add PRODUCTION-SETUP.md with complete deployment guide
- Add docs/stripe-security-fixes.md with security audit details
- Add docs/stripe-checkout-sessions.md with integration docs
- Add docs/stripe-webhooks.md with webhook configuration
- Update .env.example with all required variables including Stripe publishable key

CONFIGURATION:
- Consolidate to single .env.example template
- Update .gitignore to protect all .env variants
- Add server/Dockerfile for backend container
- Update DEPLOYMENT.md with new architecture

🔒 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 12:18:57 +01:00
Matt
97919cd4ac Update Stripe API version to 2025-10-29.clover
All checks were successful
Build and Push Docker Image / docker (push) Successful in 48s
Updated the Stripe API version from 2024-12-18.acacia to the latest
version 2025-10-29.clover as requested.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 11:22:19 +01:00
Matt
9e621042db Add WREN_DRY_RUN environment variable for safe testing
All checks were successful
Build and Push Docker Image / docker (push) Successful in 42s
Prevent accidental creation of real carbon offsets during development:
- Add WREN_DRY_RUN environment variable (default: true for dev)
- Update webhook fulfillment to use env variable instead of hardcoded value
- Log warning when in dry run mode for visibility
- Production deployments should set WREN_DRY_RUN=false

This allows safe testing with Stripe test cards without creating real Wren offset orders.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 22:07:06 +01:00
Matt
06733cb2cb Integrate Stripe Checkout and add comprehensive UI enhancements
All checks were successful
Build and Push Docker Image / docker (push) Successful in 42s
## Stripe Payment Integration
- Add Express.js backend server with Stripe Checkout Sessions
- Create SQLite database for order tracking
- Implement Stripe webhook handlers for payment events
- Integrate with Wren Climate API for carbon offset fulfillment
- Add CheckoutSuccess and CheckoutCancel pages
- Create checkout API client for frontend
- Update OffsetOrder component to redirect to Stripe Checkout
- Add processing fee calculation (3% of base amount)
- Implement order status tracking (pending → paid → fulfilled)

Backend (server/):
- Express server with CORS and middleware
- SQLite database with Order schema
- Stripe configuration and client
- Order CRUD operations model
- Checkout session creation endpoint
- Webhook handler for payment confirmation
- Wren API client for offset fulfillment

Frontend:
- CheckoutSuccess page with order details display
- CheckoutCancel page with retry encouragement
- Updated OffsetOrder to use Stripe checkout flow
- Added checkout routes to App.tsx
- TypeScript interfaces for checkout flow

## Visual & UX Enhancements
- Add CertificationBadge component for project verification status
- Create PortfolioDonutChart for visual portfolio allocation
- Implement RadialProgress for percentage displays
- Add reusable form components (FormInput, FormTextarea, FormSelect, FormFieldWrapper)
- Refactor OffsetOrder with improved layout and animations
- Add offset percentage slider with visual feedback
- Enhance MobileOffsetOrder with better responsive design
- Improve TripCalculator with cleaner UI structure
- Update CurrencySelect with better styling
- Add portfolio distribution visualization
- Enhance project cards with hover effects and animations
- Improve color palette and gradient usage throughout

## Configuration
- Add VITE_API_BASE_URL environment variable
- Create backend .env.example template
- Update frontend .env.example with API URL
- Add Stripe documentation references

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 21:45:14 +01:00
Matt
3a33221130 Hide debug logs in production
All checks were successful
Build and Push Docker Image / docker (push) Successful in 48s
- Create logger utility that only logs in development mode
- Update wrenClient.ts to use logger instead of console.log/warn
- Update OffsetOrder.tsx to use logger for debug messages
- Update config.ts to only log environment loading in dev mode
- Keeps console.error for actual errors (always shown)

Fixes: Console clutter in production deployment

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 14:58:22 +01:00
Matt
17c7a8f580 Support environment variables in env.sh for Portainer deployment
All checks were successful
Build and Push Docker Image / docker (push) Successful in 50s
- Add fallback to read from container environment variables
- Maintains backward compatibility with .env file approach
- Allows setting VITE_* vars directly in Portainer UI

This enables flexible deployment:
- File-based: Mount .env file (docker-compose)
- Env-based: Set env vars in Portainer container settings

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 14:52:39 +01:00
Matt
077deb4194 Remove container specification - use runner's default ubuntu-latest
All checks were successful
Build and Push Docker Image / docker (push) Successful in 3m31s
Match working workflow pattern from other server.
Let runner provide Docker environment directly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 14:28:21 +01:00
Matt
b9c03fa87e Remove driver specification from Buildx setup
Some checks failed
Build and Push Docker Image / docker (push) Failing after 11s
Let Buildx use default driver with --privileged container.
The 'docker' driver caused endpoint property errors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 14:27:34 +01:00
Matt
aec179ec49 Remove duplicate Docker socket mount from workflow
Some checks failed
Build and Push Docker Image / docker (push) Failing after 12s
Runner already mounts /var/run/docker.sock automatically.
Keep only --privileged flag to allow socket access.

Fixes: Error response from daemon: Duplicate mount point

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 14:26:49 +01:00
Matt
41f8fc1c76 Fix Docker socket permission issue in CI/CD workflow
Some checks failed
Build and Push Docker Image / docker (push) Failing after 1s
- Add --privileged flag and explicit Docker socket mount to container
- Configure Buildx to use 'docker' driver instead of 'docker-container'
- This avoids nested container permission issues while using full Ubuntu image

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 14:25:30 +01:00
Matt
189255a7d8 Use repository variables for registry configuration
Some checks failed
Build and Push Docker Image / docker (push) Failing after 14s
Match the working workflow pattern from other server by using
repository variables instead of hardcoded values:

- REGISTRY_HOST (code.puffinoffset.com)
- REGISTRY_USERNAME (matt)
- IMAGE_NAME (puffin-app)
- REGISTRY_TOKEN (secret with write:package permission)

This makes the workflow portable and matches the proven
working configuration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 14:22:32 +01:00
Matt
7b9901174e Use full Ubuntu image with Docker pre-installed
Some checks failed
Build and Push Docker Image / docker (push) Failing after 10m58s
Based on Zen multi-model consensus analysis:

Root cause: act_runner v0.2.13+3 maps ubuntu-latest to bare
ubuntu:22.04 which lacks Docker CLI. Newer runners use full images.

Solution: Override job container to use ghcr.io/catthehacker/ubuntu:full-22.04
which includes Docker, Buildx, Node.js, and standard CI tools.

This is the recommended approach from act_runner maintainers for
GitHub Actions compatibility.

Consensus from Gemini-2.5-pro and o3 models.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 14:08:41 +01:00
Matt
47fb07a7d2 Use proven Gitea Actions pattern from working workflow
Some checks failed
Build and Push Docker Image / docker (push) Failing after 1m32s
Switch to the pattern that works on other server:
- Run directly on ubuntu-latest (no container)
- Use docker/login-action@v3
- Use docker/setup-buildx-action@v3
- Use docker/build-push-action@v6

This matches the working workflow from another repository
and should work with the Gitea runner configuration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 13:58:49 +01:00
Matt
5a2a1c47da Replace actions/checkout with manual git clone
Some checks failed
Build and Push Docker Image / build (push) Failing after 2s
The docker:dind image doesn't include Node.js which is required
by actions/checkout@v4. Use manual git commands instead.

Changes:
- Install git via apk (Alpine package manager)
- Clone repository directly
- Checkout specific commit SHA

This approach works with docker:dind's minimal Alpine base.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 13:57:58 +01:00
Matt
683843458e Use Docker-in-Docker container for builds
Some checks failed
Build and Push Docker Image / build (push) Failing after 9s
Root cause: act_runner provides minimal environment without sudo
or Docker CLI. Cannot install packages in workflow.

Solution: Use docker:24-dind container which includes Docker CLI
and daemon. Runs with --privileged to allow nested containers.

Changes:
- Use docker:24-dind as job container
- Remove installation steps (Docker pre-installed)
- Keep simple login, build, push workflow

Also added alternative solution file showing how to configure
runner with Docker CLI for better performance.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 13:56:59 +01:00
Matt
9869355146 Install Docker CLI in workflow before use
Some checks failed
Build and Push Docker Image / build (push) Failing after 4s
Root cause: Gitea act_runner mounts Docker socket but doesn't
include Docker CLI by default to keep the image lightweight.

Solution: Install docker-ce-cli package before running any
docker commands. This allows the workflow to communicate with
the Docker daemon via the mounted socket.

Changes:
- Add step to install Docker CLI from official Docker repository
- Verify installation with docker version
- Continue with login, build, and push steps

Based on Zen expert analysis of the runner environment.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 13:55:21 +01:00
Matt
6d53650352 Switch to Docker-based workflow with CLI commands
Some checks failed
Build and Push Docker Image / build (push) Failing after 4s
Replace Kaniko approach with direct Docker CLI commands.
The Gitea runner mounts Docker socket, making Docker available
in ubuntu-latest environment.

Key changes:
- Remove container specification (Kaniko lacks shell utilities)
- Use docker login with password-stdin for authentication
- Build with docker build using multiple -t tags
- Push both latest and commit SHA tags
- Works with Docker-based Gitea runners

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 13:53:34 +01:00
Matt
8de8fc9b40 Remove --user root option from Kaniko container
Some checks failed
Build and Push Docker Image / build (push) Failing after 0s
The Kaniko executor image doesn't have traditional user management
and runs with appropriate permissions by default.

Fixes: unable to find user root: no matching entries in passwd file

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 13:51:15 +01:00
Matt
82093a0cf6 Fix CI workflow to use Kaniko for containerized runner
Some checks failed
Build and Push Docker Image / build (push) Failing after 4s
Replace Docker-based build with Kaniko executor to support
Docker-based Gitea runners that don't have Docker daemon access.

Kaniko builds container images without requiring Docker,
making it ideal for containerized CI environments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 13:50:22 +01:00
Matt
1c9c570ece Add CI/CD pipeline with Gitea Actions and Portainer deployment
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
- Create Gitea Actions workflow for automated Docker builds on push to main
- Add docker-compose.portainer.yml for production Portainer deployment
- Create comprehensive DEPLOYMENT.md guide with step-by-step instructions
- Update CLAUDE.md with CI/CD pipeline documentation

Images are built and pushed to Gitea registry at:
code.puffinoffset.com/matt/puffin-app:latest
code.puffinoffset.com/matt/puffin-app:main-<sha>

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 13:31:04 +01:00
Matt
01b232f909 Enhance UX with number formatting and improve offset workflow
- Add comma-separated number formatting for better readability in all calculator inputs
- Move offset percentage selection from calculator to offset order page for clearer workflow
- Improve project card layout with consistent height alignment in OffsetOrder
- Change number inputs to text inputs to support formatted display
- Update form messages to reflect chosen offset percentage
- Add CLAUDE.md documentation for repository guidance

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 12:51:43 +01:00
Matt
ab0dbbdb35 Refactor MobileOffsetOrder component for enhanced clarity and maintainability 2025-06-05 01:56:50 +02:00
Matt
e67e64947c Refactor MobileOffsetOrder component for improved structure and clarity 2025-06-05 01:52:03 +02:00
Matt
1a9a1b9464 Refactor MobileOffsetOrder component for improved readability and maintainability 2025-06-05 01:43:39 +02:00
Matt
fc828becdc Add MobileOffsetOrder component for CO₂ offset ordering process 2025-06-05 01:35:18 +02:00
Matt
8cc4284140 Add PWA support and implement mobile calculator component 2025-06-05 01:08:00 +02:00
Matt
4df64da3d4 removed divider 2025-06-03 19:16:32 +02:00
Matt
7690d59447 updates 2025-06-03 19:12:15 +02:00
Matt
1663329d7b updates 2025-06-03 19:07:33 +02:00
Matt
7484824246 Update favicon and logo from SVG to WebP format
Replace puffin-logo.svg with puffinOffset.webp in both the favicon link and JSON-LD structured data to use WebP image format instead of SVG.
2025-06-03 18:45:33 +02:00
Matt
eccfe856b1 Update favicon and logo from SVG to WebP format
Replace puffin-logo.svg with puffinOffset.webp in both the favicon link and JSON-LD structured data to use WebP image format instead of SVG.
2025-06-03 18:32:07 +02:00
Matt
fe801c1542 Improve responsive layout and clean up interaction handling
- Increase max widths and improve responsive spacing across components
- Add responsive grid columns (xl:grid-cols-4) for better large screen layout
- Remove redundant click area overlay and hover effects for cleaner code
- Consolidate padding management to main container level
2025-06-03 18:29:34 +02:00
Matt
8ff0ba44f8 updates 2025-06-03 18:18:42 +02:00
Matt
1f2e0e8222 updates 2025-06-03 17:07:59 +02:00
Matt
af3abb2afd edits 2025-06-03 16:49:59 +02:00
Matt
df2e11f600 updates 2025-06-03 15:25:13 +02:00
Matt
bf38357c74 updates 2025-06-03 15:21:29 +02:00
Matt
e816ea48d2 updates 2025-06-03 15:09:20 +02:00
Matt
5308cb61d1 updates 2025-06-03 15:02:29 +02:00
Matt
f9e4bc0149 Add framer-motion animations to enhance UI interactions
- Install framer-motion dependency (v12.15.0)
- Add smooth transitions to forms and buttons in TripCalculator
- Implement hover and tap animations for interactive elements
- Add entrance/exit animations for component state changes
- Enhance user experience with motion effects in Home and OffsetOrder components
2025-06-03 14:26:22 +02:00
Matt
bf0f362ab7 Merge branch 'main' of https://code.puffinoffset.com/matt/puffin-app 2025-06-03 14:08:35 +02:00
Matt
2376205371 Added lightboxes 2025-06-03 14:07:33 +02:00
Matt
96496350ee Updated with Lightboxes 2025-06-02 20:36:04 +02:00
Matt
5d0cfdef47 more fixes 2025-05-13 21:05:12 +02:00
Matt
43fca42b7f more fixes 2025-05-13 20:58:17 +02:00
Matt
444ab364a4 better connections 2025-05-13 20:48:28 +02:00
Matt
c29b15cd0b more fixes 2025-05-13 20:42:16 +02:00
Matt
7be9fc3722 more fixes 2025-05-13 20:21:05 +02:00