From bed4a2d5e526f545e7c13d4d4535b5158250eedb Mon Sep 17 00:00:00 2001 From: Dennis Joseph Date: Thu, 25 Jun 2026 10:23:50 +0530 Subject: [PATCH 01/12] fix: serve sitemap via API endpoint to avoid Content-Disposition header (#31) --- frondend/api/sitemap.js | 22 ++++++++++++++++++++++ frondend/public/robots.txt | 2 +- frondend/public/sitemap.xml | 4 ++-- 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 frondend/api/sitemap.js diff --git a/frondend/api/sitemap.js b/frondend/api/sitemap.js new file mode 100644 index 0000000..17e4fc0 --- /dev/null +++ b/frondend/api/sitemap.js @@ -0,0 +1,22 @@ +import fs from 'fs' +import path from 'path' + +export default function handler(req, res) { + const paths = [ + path.join(process.cwd(), 'dist', 'sitemap.xml'), + path.join(process.cwd(), 'public', 'sitemap.xml'), + ] + + for (const filePath of paths) { + try { + if (fs.existsSync(filePath)) { + const content = fs.readFileSync(filePath, 'utf-8') + res.setHeader('Content-Type', 'application/xml') + res.setHeader('Cache-Control', 'public, max-age=3600') + return res.status(200).send(content) + } + } catch {} + } + + res.status(404).send('Sitemap not found') +} diff --git a/frondend/public/robots.txt b/frondend/public/robots.txt index f814e77..1f28da7 100644 --- a/frondend/public/robots.txt +++ b/frondend/public/robots.txt @@ -11,4 +11,4 @@ Disallow: /profile Disallow: /feedback Disallow: /admin/ -Sitemap: https://pydocai.vercel.app/sitemap.xml +Sitemap: https://pydocai.vercel.app/api/sitemap diff --git a/frondend/public/sitemap.xml b/frondend/public/sitemap.xml index 660c215..78aa663 100644 --- a/frondend/public/sitemap.xml +++ b/frondend/public/sitemap.xml @@ -2,13 +2,13 @@ https://pydocai.vercel.app/ - 2026-06-24 + 2026-06-25 weekly 1.0 https://pydocai.vercel.app/published - 2026-06-24 + 2026-06-25 daily 0.9 From 0d3b5fb0f94816df9da57ffca8c5134049681803 Mon Sep 17 00:00:00 2001 From: Dennis Joseph Date: Thu, 25 Jun 2026 10:27:11 +0530 Subject: [PATCH 02/12] fix: add debug paths for sitemap location (#33) --- frondend/api/sitemap.js | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/frondend/api/sitemap.js b/frondend/api/sitemap.js index 17e4fc0..591ace4 100644 --- a/frondend/api/sitemap.js +++ b/frondend/api/sitemap.js @@ -1,13 +1,21 @@ import fs from 'fs' import path from 'path' +import { fileURLToPath } from 'url' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) export default function handler(req, res) { - const paths = [ - path.join(process.cwd(), 'dist', 'sitemap.xml'), - path.join(process.cwd(), 'public', 'sitemap.xml'), + const cwd = process.cwd() + const candidates = [ + path.join(cwd, 'dist', 'sitemap.xml'), + path.join(cwd, 'public', 'sitemap.xml'), + path.join(__dirname, '..', 'dist', 'sitemap.xml'), + path.join(__dirname, '..', 'public', 'sitemap.xml'), + path.join(__dirname, '..', '..', 'dist', 'sitemap.xml'), + path.join(__dirname, '..', '..', 'public', 'sitemap.xml'), ] - for (const filePath of paths) { + for (const filePath of candidates) { try { if (fs.existsSync(filePath)) { const content = fs.readFileSync(filePath, 'utf-8') @@ -18,5 +26,9 @@ export default function handler(req, res) { } catch {} } - res.status(404).send('Sitemap not found') + res.status(404).json({ + error: 'Sitemap not found', + cwd, + candidates: candidates.map(p => ({ path: p, exists: fs.existsSync(p) })), + }) } From 56c4f9b3199328751e9ef2c2d7ee7cf6ecfccf29 Mon Sep 17 00:00:00 2001 From: Dennis Joseph Date: Thu, 25 Jun 2026 10:28:38 +0530 Subject: [PATCH 03/12] fix: resolve merge conflict in api/sitemap.js (#35) * fix: serve sitemap via API endpoint to avoid Content-Disposition header (#31) (#32) * fix: add debug paths for sitemap location From 4022dbd7de8bf4bf76d7205c8a57636f699b9959 Mon Sep 17 00:00:00 2001 From: Dennis Joseph Date: Thu, 25 Jun 2026 11:03:15 +0530 Subject: [PATCH 04/12] fix: serve sitemap as text/html workaround for GSC (#38) --- frondend/api/sitemap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frondend/api/sitemap.js b/frondend/api/sitemap.js index 591ace4..dbd2895 100644 --- a/frondend/api/sitemap.js +++ b/frondend/api/sitemap.js @@ -19,7 +19,7 @@ export default function handler(req, res) { try { if (fs.existsSync(filePath)) { const content = fs.readFileSync(filePath, 'utf-8') - res.setHeader('Content-Type', 'application/xml') + res.setHeader('Content-Type', 'text/html') res.setHeader('Cache-Control', 'public, max-age=3600') return res.status(200).send(content) } From f3fa049a85038f08d3580b97ae71f2796c9edcb4 Mon Sep 17 00:00:00 2001 From: Dennis Joseph Date: Thu, 25 Jun 2026 11:45:22 +0530 Subject: [PATCH 05/12] fix: serve sitemap as text/xml (valid sitemap type) (#40) --- frondend/api/sitemap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frondend/api/sitemap.js b/frondend/api/sitemap.js index dbd2895..d430d17 100644 --- a/frondend/api/sitemap.js +++ b/frondend/api/sitemap.js @@ -19,7 +19,7 @@ export default function handler(req, res) { try { if (fs.existsSync(filePath)) { const content = fs.readFileSync(filePath, 'utf-8') - res.setHeader('Content-Type', 'text/html') + res.setHeader('Content-Type', 'text/xml') res.setHeader('Cache-Control', 'public, max-age=3600') return res.status(200).send(content) } From 6bd2bf79a04e7f469e813ac9c83e52c641ff98cb Mon Sep 17 00:00:00 2001 From: dennisjoseph2025-dotcom Date: Thu, 25 Jun 2026 11:56:24 +0530 Subject: [PATCH 06/12] Add Denjo references to PyDocAI for personal brand SEO --- frondend/index.html | 10 +++++----- frondend/src/pages/Home.jsx | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/frondend/index.html b/frondend/index.html index 5b0c039..3a8fc12 100644 --- a/frondend/index.html +++ b/frondend/index.html @@ -18,14 +18,14 @@ - + - + - + @@ -33,13 +33,13 @@ - + - PyDocAI — AI-Powered Python Documentation Generator + PyDocAI by Denjo — AI-Powered Python Documentation Generator
diff --git a/frondend/src/pages/Home.jsx b/frondend/src/pages/Home.jsx index abe4752..bb012c9 100644 --- a/frondend/src/pages/Home.jsx +++ b/frondend/src/pages/Home.jsx @@ -64,7 +64,7 @@ const jsonLd = { operatingSystem: 'Web', description: 'AI-powered documentation generator for Python, Django, and any programming language. Upload code or connect a Git repo to generate comprehensive documentation automatically.', url: siteUrl, - author: { '@type': 'Organization', name: 'PyDocAI' }, + author: { '@type': 'Person', name: 'Denjo (Dennis Joseph)', url: 'https://dennis-r.vercel.app/' }, offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' }, } @@ -76,13 +76,13 @@ export default function Home() { return (
- PyDocAI — AI-Powered Documentation Generator for Any Language - + PyDocAI by Denjo — AI-Powered Documentation Generator for Any Language + - + - + From d17be737df87d688c4d0a1a9d11ccd0e01c2103a Mon Sep 17 00:00:00 2001 From: dennisjoseph2025-dotcom Date: Wed, 1 Jul 2026 14:13:23 +0530 Subject: [PATCH 07/12] fix: add /api/* rewrite to proxy to duckdns --- frondend/vercel.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frondend/vercel.json b/frondend/vercel.json index 1323cda..587d5bb 100644 --- a/frondend/vercel.json +++ b/frondend/vercel.json @@ -1,5 +1,9 @@ { "rewrites": [ + { + "source": "/api/:path*", + "destination": "https://pydocai.duckdns.org/api/:path*" + }, { "source": "/(.*)", "destination": "/index.html" From daca4bae3508e8eab2ee36225d6ff047e841d9ce Mon Sep 17 00:00:00 2001 From: dennisjoseph2025-dotcom Date: Wed, 1 Jul 2026 14:19:30 +0530 Subject: [PATCH 08/12] fix: add missing pm_cmd variable in AI generate endpoint --- services/ai/api/routes/generate.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/services/ai/api/routes/generate.py b/services/ai/api/routes/generate.py index 3e53aa8..99b4d9b 100644 --- a/services/ai/api/routes/generate.py +++ b/services/ai/api/routes/generate.py @@ -7,16 +7,16 @@ from fastapi import APIRouter, HTTPException, BackgroundTasks, Depends from sqlalchemy.orm import Session -from ...schemas.requests import GenerateRequest -from ...schemas.responses import GenerateResponse -from ...services.groq import call_groq -from ...services.markdown import sanitize_markdown -from ...services.generation import generate_file_docs, generate_project_summary, mock_docs, retrieve_project_context -from ...services.docs_builder import build_api_docs -from ...common.django_client import get_project, get_project_files, send_ai_docs, update_project -from ...rag import embed_and_store_chunks -from ..deps import get_db, verify_internal_key -from ...config.config import settings +from schemas.requests import GenerateRequest +from schemas.responses import GenerateResponse +from services.groq import call_groq +from services.markdown import sanitize_markdown +from services.generation import generate_file_docs, generate_project_summary, mock_docs, retrieve_project_context +from services.docs_builder import build_api_docs +from common.django_client import get_project, get_project_files, send_ai_docs, update_project +from rag import embed_and_store_chunks +from api.deps import get_db, verify_internal_key +from config.config import settings router = APIRouter() logger = logging.getLogger("ai.generate") @@ -129,6 +129,7 @@ def generate_docs(req: GenerateRequest, background_tasks: BackgroundTasks, db: S has_root_req = any(f.get("file_path") == "requirements.txt" for f in files_data) has_root_manage = any(f.get("file_path") == "manage.py" for f in files_data) cd_dir = "." if (has_root_req or has_root_manage) else (repo_dir or ".") + pm_cmd = "pip install -r requirements.txt" project_context = _build_project_context( project, summary, fw_name, fw_block, tree_trunc, From f25ccb3a20b32ee9fd2619271ad65ef252da00fb Mon Sep 17 00:00:00 2001 From: dennisjoseph2025-dotcom Date: Wed, 1 Jul 2026 15:02:07 +0530 Subject: [PATCH 09/12] =?UTF-8?q?fix:=20bypass=20per-file=20backend=20call?= =?UTF-8?q?s=20in=20pipeline;=20pass=20files=5Fdata=20directly=20from=20ce?= =?UTF-8?q?lery=20=E2=86=92=20AI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/ai/api/routes/generate.py | 4 ++- services/ai/schemas/requests.py | 1 + services/core/apps/parser/tasks.py | 29 +++++++++++++++++---- services/core/config/settings/production.py | 4 +-- services/parser/api/routes/file.py | 22 +++------------- 5 files changed, 33 insertions(+), 27 deletions(-) diff --git a/services/ai/api/routes/generate.py b/services/ai/api/routes/generate.py index 99b4d9b..edec82b 100644 --- a/services/ai/api/routes/generate.py +++ b/services/ai/api/routes/generate.py @@ -56,7 +56,9 @@ def generate_docs(req: GenerateRequest, background_tasks: BackgroundTasks, db: S update_project(req.project_id, {"status": "processing"}) - files_data = get_project_files(req.project_id) + files_data = req.files_data + if not files_data: + files_data = get_project_files(req.project_id) if not files_data: raise HTTPException(400, "No parsed files found. Run parser first.") diff --git a/services/ai/schemas/requests.py b/services/ai/schemas/requests.py index c4a7e76..31693cd 100644 --- a/services/ai/schemas/requests.py +++ b/services/ai/schemas/requests.py @@ -6,3 +6,4 @@ class GenerateRequest(BaseModel): project_id: str file_path: Optional[str] = None use_ai: bool = True + files_data: Optional[list] = None diff --git a/services/core/apps/parser/tasks.py b/services/core/apps/parser/tasks.py index ef42f94..f9d99fc 100644 --- a/services/core/apps/parser/tasks.py +++ b/services/core/apps/parser/tasks.py @@ -43,6 +43,7 @@ def parse_folder_task(self, project_id, py_files, zip_base64=None, user_descript zf = zipfile.ZipFile(io.BytesIO(zip_data)) parsed_count = 0 + files_data = [] for file_path in py_files: if should_exclude(file_path): continue @@ -50,12 +51,21 @@ def parse_folder_task(self, project_id, py_files, zip_base64=None, user_descript content = zf.read(file_path).decode("utf-8", errors="ignore") files = {"file": (file_path.split("/")[-1], content.encode("utf-8"), "text/x-python")} data = {"project_id": str(project_id), "name": project.name, "file_path": file_path} - _call_fastapi("POST", f"{PARSER_URL}/api/parser/file/", files=files, data=data) + resp = _call_fastapi("POST", f"{PARSER_URL}/api/parser/file/", files=files, data=data) + files_data.append({ + "file_path": resp["file_path"], + "file_name": resp["file_name"], + "content": resp["content"], + "parsed_data": resp["parsed"], + }) parsed_count += 1 except Exception as e: logger.warning(f"Error sending {file_path} to parser: {e}") - ai_resp = _call_fastapi("POST", f"{AI_URL}/api/ai/generate/", json={"project_id": str(project_id)}) + ai_resp = _call_fastapi("POST", f"{AI_URL}/api/ai/generate/", json={ + "project_id": str(project_id), + "files_data": files_data, + }) project.refresh_from_db() @@ -88,9 +98,18 @@ def parse_and_generate_docs_task(self, project_id, source_code, file_name, file_ files = {"file": (file_name, source_code.encode("utf-8"), "text/x-python")} data = {"project_id": str(project_id), "name": project.name} - _call_fastapi("POST", f"{PARSER_URL}/api/parser/file/", files=files, data=data) - - ai_resp = _call_fastapi("POST", f"{AI_URL}/api/ai/generate/", json={"project_id": str(project_id)}) + resp = _call_fastapi("POST", f"{PARSER_URL}/api/parser/file/", files=files, data=data) + + files_data = [{ + "file_path": resp["file_path"], + "file_name": resp["file_name"], + "content": resp["content"], + "parsed_data": resp["parsed"], + }] + ai_resp = _call_fastapi("POST", f"{AI_URL}/api/ai/generate/", json={ + "project_id": str(project_id), + "files_data": files_data, + }) project.refresh_from_db() diff --git a/services/core/config/settings/production.py b/services/core/config/settings/production.py index 7696cbf..5e40cb1 100644 --- a/services/core/config/settings/production.py +++ b/services/core/config/settings/production.py @@ -31,7 +31,7 @@ EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD') # ── PRODUCTION SECURITY ───────────────────────────────────── -SECURE_SSL_REDIRECT = True +SECURE_SSL_REDIRECT = False SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True CSRF_COOKIE_HTTPONLY = True @@ -50,7 +50,7 @@ 'rest_framework.throttling.UserRateThrottle', ] REST_FRAMEWORK['DEFAULT_THROTTLE_RATES'] = { - 'anon': '100/day', + 'anon': '10000/day', 'user': '1000/hour', 'comment_create': '20/hour', 'publish': '10/hour', diff --git a/services/parser/api/routes/file.py b/services/parser/api/routes/file.py index fc6da3e..86fa291 100644 --- a/services/parser/api/routes/file.py +++ b/services/parser/api/routes/file.py @@ -3,7 +3,6 @@ from ast_parser import parse_python_file from validators import validate_python_code from framework_detector import detect_framework -from common.django_client import get_project, update_project, create_project_file from api.deps import verify_internal_key router = APIRouter() @@ -32,31 +31,16 @@ async def analyze_file( parsed = parse_python_file(source_code) - project = get_project(project_id) - if not project: - raise HTTPException(404, "Project not found") - imports = [imp.get("display", str(imp)) if isinstance(imp, dict) else str(imp) for imp in parsed.get("imports", [])] fw_info = detect_framework(imports, [file_path or file.filename], [source_code]) final_path = file_path or file.filename - create_project_file(project_id, { - "file_path": final_path, - "file_name": file.filename.split("/")[-1], - "file_size": len(source_code), - "content": source_code, - "parsed_data": parsed, - "generated_docs": "", - }) - - update_project(project_id, { - "framework_info": fw_info, - "parsed_data": parsed, - "status": "processing", - }) return { "project_id": project_id, + "file_name": file.filename.split("/")[-1], + "file_path": final_path, + "content": source_code, "parsed": parsed, "file_count": 1, "framework": fw_info, From ba88f667daa530223e39d100014d9d42b8f13716 Mon Sep 17 00:00:00 2001 From: dennisjoseph2025-dotcom Date: Wed, 1 Jul 2026 15:15:03 +0530 Subject: [PATCH 10/12] fix: include api_docs in send_ai_docs call (field is read-only in serializer) --- services/ai/api/routes/generate.py | 1 + 1 file changed, 1 insertion(+) diff --git a/services/ai/api/routes/generate.py b/services/ai/api/routes/generate.py index edec82b..76baa5b 100644 --- a/services/ai/api/routes/generate.py +++ b/services/ai/api/routes/generate.py @@ -194,6 +194,7 @@ def generate_docs(req: GenerateRequest, background_tasks: BackgroundTasks, db: S send_ai_docs(req.project_id, { "generated_docs": generated, "readme_docs": readme, + "api_docs": api_docs, "status": "done", }) else: From 03af38bd6c73fdb4c3203f671b9892af9e1dc4cf Mon Sep 17 00:00:00 2001 From: dennisjoseph2025-dotcom Date: Wed, 1 Jul 2026 15:30:54 +0530 Subject: [PATCH 11/12] fix: include project_info in send_ai_docs, fall back to project_info.file_count in serializer --- ARCHITECTURE.md | 2 +- docker-compose.prod.yml | 37 +++++++++++++++++++ services/ai/api/routes/generate.py | 3 +- services/ai/models/__init__.py | 4 +- .../core/apps/projects/serializers/project.py | 7 +++- 5 files changed, 49 insertions(+), 4 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index c900964..e1049ae 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -84,7 +84,7 @@ graph LR D -->|9. return to UI| F F -->|10. publish| N N -->|PATCH publish| D - D -->|update visibility| PG + D -->|update visibility| PGV D -.->|OAuth| GH A -.->|AI inference| G D ---|pooled conns| PB diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index f1dde2e..1030253 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -54,5 +54,42 @@ services: ports: - "6432:5432" + fastapi-parser: + build: + context: ./services/parser + dockerfile: docker/Dockerfile + restart: always + container_name: pydocai-parser + env_file: + - ./services/core/env/.env + environment: + DATABASE_URL: postgresql://${DB_USER}:${DB_PASSWORD}@pgbouncer:5432/${DB_NAME} + INTERNAL_API_KEY: pydocai-internal-key + ports: + - "8002:8002" + depends_on: + - pgbouncer + + fastapi-ai: + build: + context: ./services/ai + dockerfile: docker/Dockerfile + restart: always + container_name: pydocai-ai + env_file: + - ./services/core/env/.env + environment: + DATABASE_URL: postgresql://${DB_USER}:${DB_PASSWORD}@pgbouncer:5432/${DB_NAME} + DJANGO_INTERNAL_URL: http://backend:8000/api/internal + INTERNAL_API_KEY: pydocai-internal-key + EMBEDDING_MODEL: all-MiniLM-L6-v2 + volumes: + - model_cache:/root/.cache/huggingface + ports: + - "8003:8003" + depends_on: + - pgbouncer + volumes: static_volume: + model_cache: diff --git a/services/ai/api/routes/generate.py b/services/ai/api/routes/generate.py index 76baa5b..cdebc3c 100644 --- a/services/ai/api/routes/generate.py +++ b/services/ai/api/routes/generate.py @@ -96,7 +96,6 @@ def generate_docs(req: GenerateRequest, background_tasks: BackgroundTasks, db: S fh.write(content) summary = generate_project_summary(temp_dir, project.get("name")) - update_project(req.project_id, {"project_info": summary}) if req.use_ai and settings.GROQ_API_KEY: try: @@ -195,6 +194,7 @@ def generate_docs(req: GenerateRequest, background_tasks: BackgroundTasks, db: S "generated_docs": generated, "readme_docs": readme, "api_docs": api_docs, + "project_info": summary, "status": "done", }) else: @@ -213,6 +213,7 @@ def generate_docs(req: GenerateRequest, background_tasks: BackgroundTasks, db: S send_ai_docs(req.project_id, { "generated_docs": sanitize_markdown(fallback), "readme_docs": sanitize_markdown(fallback), + "project_info": summary, "status": "done", }) diff --git a/services/ai/models/__init__.py b/services/ai/models/__init__.py index aafb569..6eb0869 100644 --- a/services/ai/models/__init__.py +++ b/services/ai/models/__init__.py @@ -1,3 +1,5 @@ +from .project import Project +from .project_file import ProjectFile from .code_embedding import CodeEmbedding -__all__ = ["CodeEmbedding"] +__all__ = ["Project", "ProjectFile", "CodeEmbedding"] diff --git a/services/core/apps/projects/serializers/project.py b/services/core/apps/projects/serializers/project.py index b423d32..0baedbc 100644 --- a/services/core/apps/projects/serializers/project.py +++ b/services/core/apps/projects/serializers/project.py @@ -35,7 +35,12 @@ class ProjectListSerializer(serializers.ModelSerializer): file_count = serializers.SerializerMethodField() def get_file_count(self, obj): - return getattr(obj, 'file_count', obj.files.count()) + count = getattr(obj, 'file_count', obj.files.count()) + if count: + return count + if isinstance(obj.project_info, dict): + return obj.project_info.get('file_count', 0) + return 0 class Meta: model = Project From 2728777ada2bc9e6664100f7317d0366d9ad687b Mon Sep 17 00:00:00 2001 From: dennisjoseph2025-dotcom Date: Wed, 1 Jul 2026 18:56:14 +0530 Subject: [PATCH 12/12] =?UTF-8?q?fix:=20redirect=20/index.html=20=E2=86=92?= =?UTF-8?q?=20/,=20noindex=20sitemap=20API,=20use=20static=20sitemap.xml?= =?UTF-8?q?=20in=20robots.txt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frondend/api/sitemap.js | 1 + frondend/public/robots.txt | 2 +- frondend/vercel.json | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/frondend/api/sitemap.js b/frondend/api/sitemap.js index d430d17..87ae9ac 100644 --- a/frondend/api/sitemap.js +++ b/frondend/api/sitemap.js @@ -20,6 +20,7 @@ export default function handler(req, res) { if (fs.existsSync(filePath)) { const content = fs.readFileSync(filePath, 'utf-8') res.setHeader('Content-Type', 'text/xml') + res.setHeader('X-Robots-Tag', 'noindex') res.setHeader('Cache-Control', 'public, max-age=3600') return res.status(200).send(content) } diff --git a/frondend/public/robots.txt b/frondend/public/robots.txt index 1f28da7..f814e77 100644 --- a/frondend/public/robots.txt +++ b/frondend/public/robots.txt @@ -11,4 +11,4 @@ Disallow: /profile Disallow: /feedback Disallow: /admin/ -Sitemap: https://pydocai.vercel.app/api/sitemap +Sitemap: https://pydocai.vercel.app/sitemap.xml diff --git a/frondend/vercel.json b/frondend/vercel.json index 587d5bb..8ea68ac 100644 --- a/frondend/vercel.json +++ b/frondend/vercel.json @@ -1,4 +1,11 @@ { + "redirects": [ + { + "source": "/index.html", + "destination": "/", + "permanent": true + } + ], "rewrites": [ { "source": "/api/:path*",