Deploying a Receipt Management System for quickdumpnow.com and Automating Port Sheet Data Entry via Google Sheets API
What Was Done
This session involved two distinct but related infrastructure tasks:
- Deployed a receipt management system to
https://quickdumpnow.com/booksfor a trailer rental business - Built automated data entry infrastructure for a charter port sheet using Google Sheets API and Python
- Resolved CloudFront caching and routing issues that were preventing the new page from serving correctly
The core challenge was that the books page existed locally in the codebase but had never been deployed to S3, and CloudFront's custom error response configuration was masking the missing object by redirecting 404s back to the homepage.
QuickDumpNow Receipt System Deployment
File Structure and Local Development
The local repository structure for the quickdumpnow.com project is organized as follows:
/Users/cb/Documents/repos/sites/quickdumpnow.com/
├── books/
│ └── index.html
├── robots.txt
└── [other site files]
The books/index.html file was already present in the repository but had never been uploaded to the S3 origin. This is a common pattern in static site management — local development and version control can get ahead of production deployments.
S3 Deployment Strategy
Two objects were uploaded to the S3 bucket backing quickdumpnow.com:
books/index.html— The standard directory-based pathbooks— A bare key with the same content, supporting pretty URL requests
This dual-key approach is necessary because browsers request /books (without trailing slash), and S3 doesn't automatically route to index files. By uploading to both keys, we ensure both request patterns work. The bare books key handles the direct request, while books/index.html supports explicit requests.
CloudFront Configuration Issue
The CloudFront distribution for quickdumpnow.com had a custom error response configured to redirect all 4xx errors to the homepage. This is a reasonable fallback for user experience but masked the root problem: the S3 objects didn't exist yet. After uploading the pages, we invalidated the distribution cache:
# CloudFront invalidation paths
/books
/books/*
Invalidation was necessary because CloudFront had cached the 404 responses (which triggered the error response rule and redirected to homepage). The invalidation clears this stale cache. Propagation typically completes within 30–60 seconds globally.
robots.txt Update
The robots.txt file was updated to block the books endpoint from search engine indexing, since this is an internal receipt management tool, not public-facing content:
Disallow: /books
This was also uploaded to S3 and the CloudFront distribution was invalidated to ensure search engines receive the updated robots.txt immediately.
Port Sheet Automation via Google Sheets API
Architecture Overview
The port sheet automation connects three layers:
- Google Drive: Stores the JADA Port Log 2026 spreadsheet (an Excel .xls file)
- Google Sheets API: Provides programmatic access to read/write sheet data
- Python Script:
/Users/cb/Documents/repos/tools/jada_port_sheet.pyhandles local data transformations and upload logic - Apps Script:
/Users/cb/Documents/repos/sites/queenofsandiego.com/PortSheetReporter.gsbridges Sheets API calls with Drive operations
Google Sheets API Integration
The workflow retrieves the Drive file ID for the JADA Port Log 2026 spreadsheet, then uses the Sheets API to:
- List all tabs (sheets) in the workbook
- Read headers and existing rows to understand the data structure
- Dynamically create new tabs for months as needed (e.g., "April 2026")
- Append new charter entries in the correct format
The Port Log structure includes:
- Month column: Text label (e.g., "April 2026")
- Charter details: Skipper name, boat info, date, amount, notes
- Template tab: Provides row height and column width formatting reference
Data Entry for Charter Payment
A sample entry was created for a charter that paid $1,845.72:
Joseph Zurek Charter Entry
- Month: April 2026
- Amount: $1,845.72
- Status: Appended to April tab in JADA Port Log 2026
The Python script reads the Excel file structure (via openpyxl after converting .xls to .xlsx), creates the new month tab with proper formatting, inserts the charter data, and uploads the modified file back to the same Drive file ID. This preserves version history in Google Drive while ensuring all data transformations occur in a controlled, scriptable environment.
Technical Challenges and Solutions
Challenge 1: File Format Mismatch
The original file was .xls (Excel 97-2003 format). Python's openpyxl library requires .xlsx (Office Open XML). Solution: Download the file, convert it locally using openpyxl, and re-upload as xlsx. Google Sheets handles both formats transparently when stored in Drive.
Challenge 2: Sheet ID References
Google Sheets uses gid (sheet ID) internally for tab references. Initial attempts used incorrect gid values. Solution: Query the Sheets API to retrieve the actual sheet metadata, including gid values, rather than hardcoding them.
Challenge 3: Row Formatting Preservation
The original Template tab defined row heights and column widths. When adding new rows programmatically, these styles must be preserved. Solution: Read the Template tab's formatting metadata and apply matching styles to new rows in the April tab.
Key Decisions
- Dual S3 key upload: Ensures both
/booksand/books/requests work without relying on CloudFront rewrite rules - CloudFront invalidation: Required because error response rules cached before objects existed; cache invalidation is safer than waiting for TTL expiry
- Python-based file transformation: Local openpyxl processing allows version control of transformations and offline testing before Drive upload
- Sheets API over direct Drive export: API access provides programmatic tab management, which direct file exports cannot achieve
What's Next
Future improvements should focus on:
- Building a web form interface for
quickdumpnow.com/booksto accept receipt uploads and automatically generate a summary report