#!/usr/bin/env python3 """ Script to extract all backend API endpoints from router.go and compare with frontend usage. """ import re import os import sys from collections import defaultdict def extract_backend_endpoints(): """Extract all endpoints from router.go with full paths.""" router_file = 'veza-backend-api/internal/api/router.go' if not os.path.exists(router_file): return {} endpoints = defaultdict(set) with open(router_file, 'r', encoding='utf-8') as f: content = f.read() # Known route groups and their base paths # Based on reading router.go structure route_groups = { 'auth': '/auth', 'users': '/users', 'tracks': '/tracks', 'playlists': '/playlists', 'conversations': '/conversations', 'chat': '/chat', 'roles': '/roles', 'webhooks': '/webhooks', 'marketplace': '/marketplace', 'analytics': '/analytics', 'notifications': '/notifications', 'comments': '/comments', 'sessions': '/sessions', 'uploads': '/uploads', 'audit': '/audit', } # Extract endpoints by reading setup functions # Pattern: setupXxxRoutes function defines routes patterns = [ # Auth routes (r'authGroup\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/auth'), (r'protected\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/auth'), (r'registerGroup\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/auth/register'), (r'loginGroup\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/auth/login'), (r'verifyEmailGroup\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/auth/verify-email'), (r'resendVerificationGroup\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/auth/resend-verification'), (r'passwordGroup\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/password'), (r'oauthGroup\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/auth/oauth'), # User routes (r'users\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/users'), (r'protected\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/users'), # In users group # Track routes (r'tracks\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/tracks'), (r'uploadGroup\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/tracks'), (r'comments\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/tracks'), (r'commentsProtected\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/comments'), # Playlist routes (r'playlists\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/playlists'), # Chat routes (r'chat\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/chat'), (r'conversations\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/conversations'), # Role routes (r'roles\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/roles'), (r'protected\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/roles'), # In roles group # Webhook routes (r'webhooks\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/webhooks'), # Marketplace routes (r'group\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/marketplace'), (r'protected\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/marketplace'), # In marketplace group (r'createGroup\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/marketplace/products'), # Analytics routes (r'analyticsGroup\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/analytics'), # Notification routes (r'notifications\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/notifications'), # Session routes (r'sessions\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/sessions'), # Upload routes (r'uploads\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/uploads'), # Audit routes (r'audit\.(GET|POST|PUT|PATCH|DELETE)\s*\(\s*["\']([^"\']+)["\']', '/audit'), ] for pattern, base_path in patterns: for match in re.finditer(pattern, content): method = match.group(1) path = match.group(2) # Build full path if path.startswith('/'): full_path = base_path + path else: full_path = base_path.rstrip('/') + '/' + path # Normalize full_path = full_path.replace('//', '/') if not full_path.startswith('/'): full_path = '/' + full_path endpoints[full_path].add(method) return endpoints if __name__ == '__main__': endpoints = extract_backend_endpoints() print(f"Found {len(endpoints)} backend endpoints:\n") for endpoint in sorted(endpoints.keys()): methods = ', '.join(sorted(endpoints[endpoint])) print(f"{endpoint} - {methods}")