{"id":31556245,"url":"https://github.com/wal33d/address-validation-service","last_synced_at":"2026-04-15T13:32:28.787Z","repository":{"id":307365025,"uuid":"967939814","full_name":"Wal33D/address-validation-service","owner":"Wal33D","description":"High-performance location validation and geocoding service with USPS address standardization, Google Maps geocoding, intelligent caching, and comprehensive error handling.","archived":false,"fork":false,"pushed_at":"2025-09-12T04:59:01.000Z","size":296,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-04T22:52:52.352Z","etag":null,"topics":["address-standardization","address-validation","api","caching","circuit-breaker","express","geocoding","geolocation","google-maps-api","location-services","microservice","nodejs","rest-api","typescript","usps-api"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Wal33D.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-17T08:38:23.000Z","updated_at":"2025-09-12T04:59:04.000Z","dependencies_parsed_at":"2025-08-19T20:40:22.058Z","dependency_job_id":null,"html_url":"https://github.com/Wal33D/address-validation-service","commit_stats":null,"previous_names":["wal33d/location-correction","wal33d/address-validation-service"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Wal33D/address-validation-service","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wal33D%2Faddress-validation-service","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wal33D%2Faddress-validation-service/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wal33D%2Faddress-validation-service/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wal33D%2Faddress-validation-service/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Wal33D","download_url":"https://codeload.github.com/Wal33D/address-validation-service/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wal33D%2Faddress-validation-service/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31842871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T13:28:40.153Z","status":"ssl_error","status_checked_at":"2026-04-15T13:28:29.396Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["address-standardization","address-validation","api","caching","circuit-breaker","express","geocoding","geolocation","google-maps-api","location-services","microservice","nodejs","rest-api","typescript","usps-api"],"created_at":"2025-10-04T22:50:50.149Z","updated_at":"2026-04-15T13:32:28.781Z","avatar_url":"https://github.com/Wal33D.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Address Validation Service\n\nHigh-performance address validation and geocoding service using USPS and Google Maps APIs.\n\n## Overview\n\nProvides address standardization and geocoding for the CandyComp platform. Combines USPS official address validation with Google Maps geocoding for accurate property location data. Built with TypeScript and Express, featuring token caching and optimized for real estate applications.\n\n## Features\n\n- **USPS Integration** - Official USPS Web Tools API for address standardization\n- **Google Maps Geocoding** - Forward and reverse geocoding\n- **Token Management** - Automatic USPS OAuth token refresh\n- **IP Restriction** - Security through IP whitelisting\n- **Response Caching** - In-memory caching for duplicate requests\n- **TypeScript** - Full type safety with zero errors/warnings\n\n## Installation\n\n```bash\n# Install dependencies\nnpm install\n\n# Set up environment variables\ncp .env.example .env\n# Edit .env with your API credentials\n\n# Build TypeScript\nnpm run build\n\n# Run development server\nnpm run dev\n\n# Run production\nnpm start\n```\n\n## Environment Variables\n\n| Variable            | Description                  | Example        |\n| ------------------- | ---------------------------- | -------------- |\n| PORT                | Service port                 | 3715           |\n| USPS_CLIENT_ID      | USPS Web Tools Client ID     | your-client-id |\n| USPS_CLIENT_SECRET  | USPS Web Tools Client Secret | your-secret    |\n| GOOGLE_MAPS_API_KEY | Google Maps API key          | AIza...        |\n| ALLOWED_IPS         | Comma-separated allowed IPs  | ::1,127.0.0.1  |\n| NODE_ENV            | Environment mode             | production     |\n\n## API Endpoints\n\n### `POST /validate`\n\nValidate and standardize an address\n\n**Request:**\n\n```json\n{\n  \"address\": \"123 Main St\",\n  \"city\": \"New York\",\n  \"state\": \"NY\",\n  \"zip\": \"10001\"\n}\n```\n\n**Response:**\n\n```json\n{\n  \"valid\": true,\n  \"normalized\": {\n    \"address\": \"123 MAIN ST\",\n    \"city\": \"NEW YORK\",\n    \"state\": \"NY\",\n    \"zip\": \"10001-1234\"\n  },\n  \"coordinates\": {\n    \"lat\": 40.7128,\n    \"lng\": -74.006\n  }\n}\n```\n\n### `POST /geocode`\n\nForward geocode an address\n\n**Request:**\n\n```json\n{\n  \"address\": \"123 Main St, New York, NY 10001\"\n}\n```\n\n**Response:**\n\n```json\n{\n  \"lat\": 40.7128,\n  \"lng\": -74.006,\n  \"formattedAddress\": \"123 Main St, New York, NY 10001, USA\",\n  \"placeId\": \"ChIJ...\"\n}\n```\n\n### `POST /reverse-geocode`\n\nGet address from coordinates\n\n**Request:**\n\n```json\n{\n  \"lat\": 40.7128,\n  \"lng\": -74.006\n}\n```\n\n**Response:**\n\n```json\n{\n  \"address\": \"123 Main St\",\n  \"city\": \"New York\",\n  \"state\": \"NY\",\n  \"zip\": \"10001\",\n  \"formattedAddress\": \"123 Main St, New York, NY 10001, USA\"\n}\n```\n\n### `GET /health`\n\nHealth check endpoint\n\n## Development\n\n```bash\n# Run with hot reload\nnpm run dev\n\n# Type checking\nnpm run type-check\n\n# Linting\nnpm run lint\nnpm run lint:fix\n\n# Format code\nnpm run format\nnpm run format:check\n\n# Clean build\nnpm run clean\n```\n\n## Testing\n\n```bash\n# Run all tests\nnpm test\n\n# Run with coverage\nnpm run test:coverage\n\n# Watch mode\nnpm run test:watch\n```\n\n## Architecture\n\n### Service Flow\n\n1. Receive address validation request\n2. Authenticate with USPS (cached token if available)\n3. Validate address through USPS\n4. Geocode through Google Maps\n5. Return standardized address with coordinates\n\n### Key Components\n\n- **USPS Client** - Handles OAuth token management and API calls\n- **Google Maps Client** - Geocoding and reverse geocoding\n- **Cache Manager** - In-memory caching for performance\n- **IP Middleware** - Security through IP whitelisting\n- **Error Handler** - Comprehensive error handling with fallbacks\n\n## Production Deployment\n\n### Using PM2\n\n```bash\n# Build for production\nnpm run build\n\n# Start with PM2\npm2 start ecosystem.config.js\n\n# Monitor\npm2 monit\n\n# View logs\npm2 logs service-address-validation\n\n# Restart\npm2 restart service-address-validation\n```\n\n### Manual Start\n\n```bash\nnpm start\n```\n\n## GitHub Actions Deployment\n\nThe repository includes a GitHub Actions workflow that automatically builds and deploys the service when you push to the `main` branch.\n\n### Required GitHub Secrets\n\nConfigure these secrets in your GitHub repository settings:\n\n#### SSH Connection\n\n- `LINODE_HOST` - Server IP or hostname\n- `LINODE_USERNAME` - SSH username (e.g., `puppeteer-user`)\n- `LINODE_PASSWORD` - SSH password for authentication\n\n#### Application Environment\n\n- `USPS_CLIENT_ID` - USPS Web Tools Client ID\n- `USPS_CLIENT_SECRET` - USPS Web Tools Client Secret\n- `GOOGLE_MAPS_API_KEY` - Google Maps API key\n- `ALLOWED_IPS` - Comma-separated allowed IPs\n- `NODE_ENV` - Environment setting (e.g., `production`)\n\n### Deployment Process\n\n1. Builds TypeScript project\n2. Copies built files to server\n3. Creates `.env` file from GitHub secrets\n4. Installs production dependencies\n5. Restarts PM2 process\n\n## Performance\n\n- **Caching** - In-memory cache for duplicate requests\n- **Token Reuse** - USPS OAuth tokens cached until expiry\n- **Connection Pooling** - Optimized HTTP connections\n- **Async Processing** - Non-blocking operations\n\n## Security\n\n- **IP Whitelisting** - Only configured IPs can access\n- **Input Validation** - All inputs validated before processing\n- **Error Sanitization** - Sensitive data removed from error responses\n- **Rate Limiting** - Built-in request throttling\n\n## License\n\n© 2024 Waleed Judah. All rights reserved.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwal33d%2Faddress-validation-service","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwal33d%2Faddress-validation-service","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwal33d%2Faddress-validation-service/lists"}