remove debug loggings
This commit is contained in:
@@ -293,5 +293,26 @@ All database queries use parameterized statements (`?` placeholders).
|
|||||||
|
|
||||||
`nginx.conf` contains **location blocks only** — drop them into an existing `server { }` block. Adjust the `alias` paths to match your deployment layout.
|
`nginx.conf` contains **location blocks only** — drop them into an existing `server { }` block. Adjust the `alias` paths to match your deployment layout.
|
||||||
|
|
||||||
When running without nginx (Docker Compose or local dev), the Python backend serves the frontend directly at the base URL.
|
When running without nginx (Docker Compose or local dev), the Python backend serves the frontend directly at the base URL. Set `"production": true` in config to disable backend static serving (nginx handles it).
|
||||||
|
|
||||||
|
### Caching strategy
|
||||||
|
|
||||||
|
The nginx config uses a layered caching strategy designed for deployments behind Cloudflare or other CDNs:
|
||||||
|
|
||||||
|
| Resource | `Cache-Control` | Why |
|
||||||
|
|---|---|---|
|
||||||
|
| `/s/` (index.html) | `no-store` | Never cached by CDN or browser. This is the HTML entry point (~2KB) that contains `?v=` cache-buster query strings for CSS/JS. Must always be fresh so that version bumps take effect immediately. |
|
||||||
|
| `/s/static/*.css?v=…` | `no-cache` | Cached but revalidated on each request. The `?v=` query string acts as a cache key — Cloudflare and browsers treat each version as a distinct resource. Bump the `?v=` value in `index.html` whenever CSS/JS files change. |
|
||||||
|
| `/s/static/*.js?v=…` | `no-cache` | Same as CSS. |
|
||||||
|
| `/s/api/*`, `/s/<code>` | (proxied) | Not cached by nginx; backend controls caching via response headers. |
|
||||||
|
|
||||||
|
### Updating static files
|
||||||
|
|
||||||
|
When you modify `style.css` or `app.js`:
|
||||||
|
|
||||||
|
1. Deploy the updated files to the server
|
||||||
|
2. Bump the `?v=` value in `static/index.html` (e.g. `?v=20260318` → `?v=20260319`)
|
||||||
|
3. Reload nginx (`nginx -s reload`)
|
||||||
|
|
||||||
|
Since `index.html` has `no-store`, browsers and Cloudflare always fetch the latest version, which in turn references the new `?v=` URLs for CSS/JS — busting all downstream caches automatically. No manual CDN purge is needed.
|
||||||
|
|
||||||
|
|||||||
+2
-20
@@ -177,7 +177,6 @@ function setupUrlInput() {
|
|||||||
input.addEventListener('input', () => {
|
input.addEventListener('input', () => {
|
||||||
clearTimeout(_lookupTimer);
|
clearTimeout(_lookupTimer);
|
||||||
const val = input.value.trim();
|
const val = input.value.trim();
|
||||||
console.log('[input event] value:', val);
|
|
||||||
if (!val) {
|
if (!val) {
|
||||||
clearResult();
|
clearResult();
|
||||||
if (state.isAdmin) renderAdminPanel();
|
if (state.isAdmin) renderAdminPanel();
|
||||||
@@ -190,7 +189,6 @@ function setupUrlInput() {
|
|||||||
});
|
});
|
||||||
input.addEventListener('keydown', (e) => {
|
input.addEventListener('keydown', (e) => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
console.log('[keydown] Enter pressed');
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
handleEnter();
|
handleEnter();
|
||||||
}
|
}
|
||||||
@@ -198,29 +196,23 @@ function setupUrlInput() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function lookupUrl(url) {
|
async function lookupUrl(url) {
|
||||||
console.log('[lookupUrl] called with:', url);
|
|
||||||
if (!isValidUrl(url)) {
|
if (!isValidUrl(url)) {
|
||||||
console.log('[lookupUrl] invalid URL, clearing');
|
|
||||||
clearResult();
|
clearResult();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await apiGet('/api/lookup?url=' + encodeURIComponent(url));
|
const res = await apiGet('/api/lookup?url=' + encodeURIComponent(url));
|
||||||
console.log('[lookupUrl] response status:', res.status);
|
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
console.log('[lookupUrl] found existing:', data);
|
|
||||||
state.currentMeta = data;
|
state.currentMeta = data;
|
||||||
renderMeta(data);
|
renderMeta(data);
|
||||||
setStatus('exists', 'ok');
|
setStatus('exists', 'ok');
|
||||||
} else {
|
} else {
|
||||||
console.log('[lookupUrl] not found, clearing meta');
|
|
||||||
state.currentMeta = null;
|
state.currentMeta = null;
|
||||||
clearResult();
|
clearResult();
|
||||||
setStatus('', '');
|
setStatus('', '');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch {
|
||||||
console.error('[lookupUrl] error:', e);
|
|
||||||
clearResult();
|
clearResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,12 +221,8 @@ async function handleEnter() {
|
|||||||
clearTimeout(_lookupTimer); // cancel any pending debounced lookup
|
clearTimeout(_lookupTimer); // cancel any pending debounced lookup
|
||||||
const input = document.getElementById('url-input');
|
const input = document.getElementById('url-input');
|
||||||
const url = input.value.trim();
|
const url = input.value.trim();
|
||||||
console.log('[handleEnter] url:', url);
|
|
||||||
console.log('[handleEnter] state.apiKey:', state.apiKey ? '(set)' : '(empty)');
|
|
||||||
console.log('[handleEnter] state.currentMeta:', state.currentMeta);
|
|
||||||
|
|
||||||
if (!url || !isValidUrl(url)) {
|
if (!url || !isValidUrl(url)) {
|
||||||
console.log('[handleEnter] invalid/empty URL, clearing');
|
|
||||||
clearResult();
|
clearResult();
|
||||||
setStatus('', '');
|
setStatus('', '');
|
||||||
return;
|
return;
|
||||||
@@ -242,20 +230,16 @@ async function handleEnter() {
|
|||||||
|
|
||||||
// If the debounced lookup already found this URL exists, just show it
|
// If the debounced lookup already found this URL exists, just show it
|
||||||
if (state.currentMeta && state.currentMeta.original_url === url) {
|
if (state.currentMeta && state.currentMeta.original_url === url) {
|
||||||
console.log('[handleEnter] URL already found by lookup, showing existing');
|
|
||||||
setStatus('exists', 'ok');
|
setStatus('exists', 'ok');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new short URL
|
// Create a new short URL
|
||||||
console.log('[handleEnter] proceeding to create...');
|
|
||||||
setStatus('creating…', '');
|
setStatus('creating…', '');
|
||||||
try {
|
try {
|
||||||
const res = await apiPost('/api/shorten', { url: url });
|
const res = await apiPost('/api/shorten', { url: url });
|
||||||
console.log('[handleEnter] POST /api/shorten status:', res.status);
|
|
||||||
if (res.status === 201) {
|
if (res.status === 201) {
|
||||||
const shortUrl = await res.text();
|
const shortUrl = await res.text();
|
||||||
console.log('[handleEnter] created:', shortUrl);
|
|
||||||
const code = shortUrl.split('/').pop();
|
const code = shortUrl.split('/').pop();
|
||||||
const metaRes = await apiGet('/api/urls/' + encodeURIComponent(code));
|
const metaRes = await apiGet('/api/urls/' + encodeURIComponent(code));
|
||||||
if (metaRes.ok) {
|
if (metaRes.ok) {
|
||||||
@@ -267,11 +251,9 @@ async function handleEnter() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const err = await res.json().catch(() => null);
|
const err = await res.json().catch(() => null);
|
||||||
console.log('[handleEnter] create failed:', res.status, err);
|
|
||||||
setStatus(err?.error || 'error', 'err');
|
setStatus(err?.error || 'error', 'err');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch {
|
||||||
console.error('[handleEnter] network error:', e);
|
|
||||||
setStatus('network error', 'err');
|
setStatus('network error', 'err');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -7,7 +7,7 @@
|
|||||||
<meta name="description" content="URL Shortener">
|
<meta name="description" content="URL Shortener">
|
||||||
<title>Short · URL Shortener</title>
|
<title>Short · URL Shortener</title>
|
||||||
<link rel="stylesheet" href="static/fonts.css">
|
<link rel="stylesheet" href="static/fonts.css">
|
||||||
<link rel="stylesheet" href="static/style.css?v=20260318">
|
<link rel="stylesheet" href="static/style.css?v=20260318b">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="bg" aria-hidden="true"></div>
|
<div id="bg" aria-hidden="true"></div>
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
|
|
||||||
<div id="toast" class="toast" aria-live="polite"></div>
|
<div id="toast" class="toast" aria-live="polite"></div>
|
||||||
|
|
||||||
<script src="static/app.js?v=20260318" defer></script>
|
<script src="static/app.js?v=20260318b" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user