Files
padelnomics/.env.dev.sops
Deeman 0fa2bf7c30 feat: admin articles grouped view, live stats, + bug fixes
Admin articles list:
- Group EN/DE language variants into a single row (grouped by url_path)
- Language chips (● EN/● DE) coloured by status: green=live, amber=scheduled, blue=draft
- Inline View ↗ (live only) and Edit buttons per variant — one-click access
- Filter by language switches back to flat single-row view
- Live HTMX polling of article counts while generation runs (every 3s, self-terminates)
- Table overflow fix: card gets overflow:hidden, table wrapped in overflow-x:auto scroll div

Bug fixes:
- X-Forwarded-Proto: pass $http_x_forwarded_proto through Nginx so Quart sees https
- pipeline_routes.py: fix relative import for analytics module (from .analytics → from ..analytics)
- Scheduled articles: redirect to parent path instead of 404 when not yet published
- city-cost-de: change priority_column from population to padel_venue_count
- Quote wizard step 4: make location_status required
- Article generation: use COUNT(*) instead of 501-sentinel hack for row counts
- Makefile: pin Tailwind v4.1.18, add dev/help targets, uv run python, .PHONY

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 20:17:28 +01:00

77 lines
9.9 KiB
Plaintext

#ENC[AES256_GCM,data:9JNa0g==,iv:KnGl3/4KQWkVnFXn9iKU5z5Ys6KXWOnSEoE/Jjks2pw=,tag:ZD3nrOQmhUjPkZiwtV330g==,type:comment]
APP_NAME=ENC[AES256_GCM,data:Vic/MJYoxZo8JAI=,iv:n1SEGQaGeZtYMtLmDRFiljDBbNKFvCzZPNtaFBNauYY=,tag:Smsd20Ba56QZKVFpRmhRPQ==,type:str]
SECRET_KEY=ENC[AES256_GCM,data:a3Bhj3gSQaE3llRWBYzpjoFDhhhSsNee67jXJs7+qn4=,iv:yvrx78X5Ut4DBSlmBnIn09ESVc/tuDiwiV4njmjcvko=,tag:cbFUTAEpX+isQD9FCVllsw==,type:str]
BASE_URL=ENC[AES256_GCM,data:LcbPDZf9Pwcuv7RxN9xhNfa9Tufi,iv:cOdjW9nNe+BuDXh+dL4b5LFQL2mKBiKV0FaEsDGMAQc=,tag:3uAn3AIwsztIfGpkQLD5Fg==,type:str]
DEBUG=ENC[AES256_GCM,data:qrEGkA==,iv:bCyEDWiEzolHo4vabiyYTsqM0eUaBmNbXYYu4wCsaeE=,tag:80gnDNbdZHRWVEYtuA1M2Q==,type:str]
#ENC[AES256_GCM,data:YmlGAWpXxRCqam3oTWtGxHDXC+svEXI4HyUxrm/8OcKTuJsYPcL1WcnYqrP5Mf5lU5qPezEXUrrgZy8vjVW6qAbb0IA2PMM4Kg==,iv:dx6Dn99dJgjwyvUp8NAygXjRQ50yKYFeC73Oqt9WvmY=,tag:6JLF2ixSAv39VkKt6+cecQ==,type:comment]
ADMIN_EMAILS=ENC[AES256_GCM,data:hlG8b32WlD4ems3VKQ==,iv:wWO08dmX4oLhHulXg4HUG0PjRnFiX19RUTkTvjqIw5I=,tag:KMjXsBt7aE/KqlCfV+fdMg==,type:str]
#ENC[AES256_GCM,data:b2wQxnL8Q2Bp,iv:q8ep3yUPzCumpZpljoVL2jbcPdsI5c2piiZ0x5k10Mw=,tag:IbjkT0Mjgu9n+6FGiPVihg==,type:comment]
DATABASE_PATH=ENC[AES256_GCM,data:pEpMUrL7ZHAzMT4=,iv:eDGudDVsW5vF0sENri7gQrFlCEdoWYP6hT5ZeXXs3Zg=,tag:Gl91C6uRdCiJ7Jo1Z/MQsg==,type:str]
#ENC[AES256_GCM,data:xVzlko4=,iv:glHTshoRIkIaJNpn4onyAxPOtXTsNh/JohXJyyu4Ars=,tag:fQ/53HdxYXs2JTMx6O8rrA==,type:comment]
MAGIC_LINK_EXPIRY_MINUTES=ENC[AES256_GCM,data:Ua4=,iv:ou1kEn+fa42lZDsXaPvpodJcvAF+EZC9UIGNK/tBV/U=,tag:+ed8Bm/8pdIksH7O2X8WwQ==,type:str]
SESSION_LIFETIME_DAYS=ENC[AES256_GCM,data:/gk=,iv:kKWy+FaoLp8kAWpZzpoUHX8nVFRaA4yuTTVzN2TSYTs=,tag:QypZTVmTo4lXd7PKTWrBdA==,type:str]
#ENC[AES256_GCM,data:8HLEkeUESRt3bOxIQsma,iv:kzt8+SFNJw2r3LqwwQPzs9bCdacYSfHWPzIvTxARI4k=,tag:n+F13eILUiJCZ3NtQdo26g==,type:comment]
#ENC[AES256_GCM,data:cGkjKPIfdOPWoZFEXTAgw5lsu0LIcNhu1y3ab47kKbVEZMiCk+0KrEUNJcqbQ+ProBQ6F6N38PUhUl0lhKKjMqjepMZUUrUTqFp0Tw==,iv:WyFISLnRnSSOkra/p7bOs5BQWx+qFaaeeZM50EdrIgA=,tag:UM0EiRGy+RFXfdJqRuv3Jw==,type:comment]
#
#ENC[AES256_GCM,data:icBc0Zv+oedobh8DOTwV2Fc+N0C9CqjZvLciC1dmEIygr/P5oOBLH9Bnhf7XW3X+fiLUtLPQPUIh9CjX+wVeX+MpUZj8ksS0meoz1O2kSBs=,iv:oWreqF6QxaFZn2r35uqY7yy/nItwy3k3VuXAcLyqMbI=,tag:ezQO+m6qkQSEwe17vYtYcw==,type:comment]
#ENC[AES256_GCM,data:BmlWl0f3aiOrEVglJisqHb507/ipmyRCUvkygs2jBfh2gw3BJgrCAAqoK+DekvIls2myRn7RynqWTMZKGXtJMHu5SEA8,iv:QjPoSzyNl6CBYmJAd2OfFEEoXO3jz0LL2VNegP0mY8Q=,tag:miTvj9PK1a00BKaAjUTICw==,type:comment]
#ENC[AES256_GCM,data:kzSYQCopgU9wXpw61WGfYpRtOjV3iEVvZ09RP4OqVl+Rqnd2wCKREKKrB7F15bp4BB3OzMo=,iv:TFFpROfYKaUlWQm3ISYkyYdZCarSJbqHItLMUplYiXc=,tag:Xbk3ii3DYE4yPe8cJOt+Tw==,type:comment]
#ENC[AES256_GCM,data:qbh0Mnu6wEbDaBideJQCZa74G/DqSWuoiy22zCGoKqKZ2YVQEf0QxRCO/DgOD8rdp1Neqp8u4oE=,iv:dKV76b8sT1ghlyEadeAqTjtNTXrBp9n5ZbGMGi2/GyU=,tag:1HsI5iDekTqxeYmcEpL3HA==,type:comment]
#ENC[AES256_GCM,data:kTLnLnwPVVDFKYncBbFjGmnbxmNfpPXSpKyZu5ZQx6PeVs5s6hpDa55zRXxAetyBAHsmV99ZV2q1NTDXF6Q=,iv:m/ulRFQcGl15vi2ohMwVeYBmcRtp274ROiKXPsyJkfQ=,tag:T0E5p4d/inHyuupbg7bZHQ==,type:comment]
#ENC[AES256_GCM,data:aziyEFGCGxbc+q2ma2QN4MvdhQ6bnYuZA7Cgqr6p3zGjPG3oybTWwILejJqD2lHmULXh0UN0qco=,iv:XZwwEUOAEXIUyXiiHFS/bdL91bWKIhZ5IzcXWXAR63Y=,tag:JLsDM4s2yh4aBFQtxWLhDA==,type:comment]
#ENC[AES256_GCM,data:JroBWIbSs5a7+lg/AtBNPxgbtxaztjmVzI1JXuhBmfWD45Qp+w8ePZg9PA1FYzPtEATPHso6m3tZdMTrPtv4Jj6ig/+KHOLn,iv:CbJp6MHOU4yk9OdynQTPwVgZj9Djw9IC9TE90go5RDk=,tag:NTVDg0mFeZsxfVeIFwFhPw==,type:comment]
#
#ENC[AES256_GCM,data:JDxXJ3IJVaBF+MOWe0WXBOPnee48RyjNDtflwVM2FFbLSp1h2uYf6+aRjC4w6pb/R1pl9+AzjjlQaTukjQVwXfbBVKH8SAbhOdU=,iv:K9kvgAbltLIcBo4vZ8NUiaL/Ik+x5Arl9Pj5sh3SIHo=,tag:IjneoyVD+dxd6N2PVV43ww==,type:comment]
RESEND_API_KEY=
EMAIL_FROM=ENC[AES256_GCM,data:QX6duq5wx3z98o39nRXTrPpNXwI=,iv:ikpykHOeHRay+k3B4MvHn2SOuHNGOIuvjetOt+cjTrQ=,tag:8ryM56ogWySp9RAv0/ABTg==,type:str]
LEADS_EMAIL=ENC[AES256_GCM,data:aVFgeh0Yx7W/88noeURvf8rirv8=,iv:5KjsCMAsu1Ywz4BI2JjB1KmQ6QM94U1zlNGJ3BKl7Uo=,tag:voi0kjdhz0SsOQHqtMID4Q==,type:str]
RESEND_WEBHOOK_SECRET=
#ENC[AES256_GCM,data:1HqXvAspvNIUNpCxJwge3mEsyO0Y/EWvD3vbLxkgGqIex0hABcupX/Nzk15u8iOY5JWvvEuAO414MNt6mFvnWBDpEw==,iv:N7gCzTNJAR/ljx5gGsX+ieZctya8vQbCIb3hw49OhXg=,tag:PJKNyzhrit5VgIXl+cNlbQ==,type:comment]
#ENC[AES256_GCM,data:do6DZ/1Osc5y4xseG8Q8bDX84JBHLzvmVbHiqxP7ChlicmzYBkZ85g43BuM7V0KInFTFgvaC8xmFic+2d37Holuf1ywdAjbLkRhg,iv:qrNmhPbmFDr2ynIF5EdOLZl3FI5f68WDrxuHMkAzuuU=,tag:761gYOlEdNM+e1//1MbCHg==,type:comment]
#ENC[AES256_GCM,data:dseLIQiUEU20xJqoq2dkFho9SnKyoyQ8pStjvfxwnj8v18/ua0TH/PDx/qwIp9z5kEIvbsz5ycJesFfKPhLA5juGcdCbi5zBmZRWYg==,iv:7JUmRnohJt0H5yoJXVD3IauuJkpPHDPyY02OWHWb9Nw=,tag:KcM6JGT01Aa1kTx+U30UKQ==,type:comment]
#ENC[AES256_GCM,data:GgXo4zkhJsxXEk8F5a/+wdbvBUGN00MUAutZYLDEqqN4T1rZu92fioOLx7MEoC0b8i61,iv:f1hUBoZpmnzXNcikf/anVNdRSHNwVmmjdIcba3eiRI4=,tag:uWpF40uuiXyWqKrYGyLVng==,type:comment]
PADDLE_API_KEY=
PADDLE_CLIENT_TOKEN=
PADDLE_WEBHOOK_SECRET=
PADDLE_NOTIFICATION_SETTING_ID=
PADDLE_ENVIRONMENT=ENC[AES256_GCM,data:KIGNxEaodA==,iv:SRebaYRpVJR0LpfalBZJLTE8qBGwWZB/Fx3IokQF99Q=,tag:lcC56e4FjVkCiyaq41vxcQ==,type:str]
#ENC[AES256_GCM,data:2Hs7ds2ppeRqKB7EiAAbWqlainKdZ+eTYZSvPloirT4Hlsuf+zTwtJTA6RzHNCuK4em//jhOx8R2k80I,iv:1N6CNPqYWp3z8lm5e2Vp6OlpgHdMOiD7dsEYp23nMtA=,tag:ulWP/BFFoLljLMVCrsgizw==,type:comment]
UMAMI_API_URL=ENC[AES256_GCM,data:oX/m95YB+S2ziUKoxDhsDzMhGZfxppw+w603tQ==,iv:GAj7ccF6seiCfLAh2XIjUi13RpgNA3GONMtINcG+KMw=,tag:mUfRlvaEWrw2QWFydtnbNA==,type:str]
UMAMI_API_TOKEN=
#ENC[AES256_GCM,data:HTG/nKNl9NMicZVt5nU=,iv:MfRqX6tzdl6SC61xjRxTrVRpTWGmmqslL/Vdy88Jtyo=,tag:NhOgm3+qJelmQaAAnITFKA==,type:comment]
RATE_LIMIT_REQUESTS=ENC[AES256_GCM,data:hy3B,iv:kouDI24Gac/S7aQMXRcl+emwE6/WU+F9egNhQ+MayrA=,tag:iZXV92kqnS0MppvW6Km5oQ==,type:str]
RATE_LIMIT_WINDOW=ENC[AES256_GCM,data:vE8=,iv:lS6cQX3VzHeVrlYHQTXYGgib1rYI9G4XoW/f5YSjVWs=,tag:3Bn8PIktDxD7HvUTHw6mnw==,type:str]
#ENC[AES256_GCM,data:KRlMK35PPFBTe7FOkbanuskbA4oFj51Fg290lRtwyHKoJxi7fHg7cueojwCiRSJestRguwV8g9UP4MC9bKzWssdFqvfdr7XEUuA3a+WWD9I=,iv:RZhJJS6tNZHecxn/862nnl8dg8OwsVYB/R0yPxYMXgw=,tag:dqXgcU8OSyJzOPJp+7Z+cA==,type:comment]
LITESTREAM_R2_BUCKET=
LITESTREAM_R2_ACCESS_KEY_ID=
LITESTREAM_R2_SECRET_ACCESS_KEY=
LITESTREAM_R2_ENDPOINT=
#ENC[AES256_GCM,data:4To0MRZIt3HxO7qjh4E=,iv:/caczOlTPECDF6mA1PKO8Xm4NeR1RZjgpt2Vuq+rfkQ=,tag:S/UGMqHZQX/Q20N+Ah30WQ==,type:comment]
DUCKDB_PATH=ENC[AES256_GCM,data:sql4dtOLeX1aY/kdaxAzCk47hm3t,iv:S63x40+5blcF8qYxMjqUhs2moukuy2yEQRPbUvXZSYo=,tag:lTLYjtyZNiv06o/hm6Grxg==,type:str]
SERVING_DUCKDB_PATH=ENC[AES256_GCM,data:xE05ajjqmYggI9oz4w1GBucUn0bI,iv:/C3D+iWSNk1XJ/xclTzdJTqOHR12Gwmo1xIxH/4nyL0=,tag:eNcgrb+QvL/y1jE8mb0DHg==,type:str]
LANDING_DIR=ENC[AES256_GCM,data:PNPOE7/MV/iQ24mf,iv:lg486nzb/vlOyTHVQ0HEO4fK18IEJNnuSc/CrQwUsHk=,tag:zecZp+Xfw+dL5GtUeIOg/A==,type:str]
#ENC[AES256_GCM,data:bsiiPYvTz0LtdIgopkPEtcgmtDzZU0W6uton/sqm++5UymV33B0m47LIpdH9xQurQtmoZwMCBkAe0FCqqz62D1dAIH1Q6lzzLqg=,iv:rr7aShvtJtAnBzcbr/O0wOONpDBzwbR/Wbx/YPPsKpM=,tag:YH1wdokUuudFvagnPuT8aA==,type:comment]
REPO_DIR=ENC[AES256_GCM,data:vg==,iv:TNMZ6lrajWy6C9q89/AbRkBawBc2YaGsn2elbO8V2Wk=,tag:va77fkt8VDpPG8pZu490uw==,type:str]
WORKFLOWS_PATH=ENC[AES256_GCM,data:PehxEUMb1K3F1557BY3IqKD7sbJcoaIjnQvboBRJ1g==,iv:WfniguOksC3onCSyDlBpfKC8bE9DAt7evoeYX0K0lvE=,tag:sdRWDqkk9dtuESvfbRBfCQ==,type:str]
ALERT_WEBHOOK_URL=
NTFY_TOKEN=
#ENC[AES256_GCM,data:BCyQYjRnTx8yW9A=,iv:4OPCP+xzRLUJrpoFewVnbZRKnZH4sAbV76SM//2k5wU=,tag:HxwEp7VFVZUN/VjPiL/+Vw==,type:comment]
PROXY_URLS=ENC[AES256_GCM,data:CzRaK0piUQfvuYYsdz0i2MEQIphKi0BhNvHw9alo46aTH+kqEKvoS7dKEKzyU9VJ4TyNweInlVMxB962DsvRoBtnHwo/pUmYtVeEr2881clNgEiZVYRDFRdEbpULcLPDJa3ey1leqAAHlmiL0RQ6Qa57gPCOVBzVG6npGLKO+K8XVIb+BZMs9kEUOlw7iuqTJW5xPN/t4X/jHidEqfTSAl9b4vU4bsYVuY3yQrL+/V5QpTbyXlf+cMq3flpA3zE2Fxhalzg+c/wHMTrCksFwrCkrInW0kY9yPkA7usUWr1xwwaV3wIDoNQsLXpMd/3RztipNvKtOMRhRJOmjzP7BKhCJvvvKTV5p+mBCulFijbMQgArg3BqcFanfw3YZ4wPd4hp8q/vOhE/U9Wu0yrMmyWYFHYGQnFVARlBH7pwn/ez8W4KqRFveEAuev9CE7K7s5RqzPLelSkoa9UuiiULJ+t0LFgKlgxuLtQ8GdFdgsmBCxY/4U/xzvNdC82hD549z5nMWWlaUJm4onPWirT/RYm7j3v6z4mmNImI2W6rCNbvEvsXwWsciquVaBIgReA47p6/GTzZ9VZMyGr4PdzB87BJGAgX1W57WNdPAsRIF49XP2BU72RtRFxsUG8Ha2dc=,iv:a10Vpk7Zv8QqORuEcMlpcvtHO/zjBLaFphWPYBXwysc=,tag:8N66/R+CLqEZ45wj+tCt6w==,type:str]
RECHECK_WINDOW_MINUTES=ENC[AES256_GCM,data:YWM=,iv:iY5+uMazLAFdwyLT7Gr7MaF1QHBIgHuoi6nF2VbSsOA=,tag:dc6AmuJdTQ55gVe16uzs6A==,type:str]
PROXY_URLS_FALLBACK=ENC[AES256_GCM,data:95rwI7kKUj1YxLpjChtrM4f2EFUDzQdAg1e1MOHnLwQ9ZY54UNH7v4JcqTsvDk9D+0N/BIdwFSDi7pnCSd6BWFV+cQ==,iv:rm9HdBsibSne7JR6vWl+ao/GHb1rbuVdZZDUWhVbTnE=,tag:NJ2STxmFZPvFayfTrEEYbg==,type:str]
CIRCUIT_BREAKER_THRESHOLD=
#ENC[AES256_GCM,data:ZcX/OEbrMfKizIQYq3CYGnvzeTEX7KsmQaz2+Jj1rG5tbTy2aljQBIEkjtiwuo8NsNAD+FhIGRGVfBmKe1CAKME1MuiCbgSG,iv:4BSkeD3jZFawP09qECcqyuiWcDnCNSgbIjBATYhazq4=,tag:Ep1d2Uk700MOlWcLWaQ/ig==,type:comment]
GSC_SERVICE_ACCOUNT_PATH=
GSC_SITE_URL=
BING_WEBMASTER_API_KEY=
BING_SITE_URL=
#ENC[AES256_GCM,data:ECsuDMQipS6YmFpSm1vqCsR2fUW2zN1Mg9VcUlw0roM=,iv:j+F6Akx2bklGMkFTux230YcZjMibA+Qp+qvgkGXl4Jw=,tag:7aO0wbmP/qB73wLgtiSJ2w==,type:comment]
GEONAMES_USERNAME=ENC[AES256_GCM,data:aSkVdLNrhiF6tlg=,iv:eemFGwDIv3EG/P3lVHGZj96MieIsr85e4xYmEIpZyfM=,tag:McpZMNOIO3FDkSebae2gOQ==,type:str]
CENSUS_API_KEY=ENC[AES256_GCM,data:qqG971573aGq9MiHI2xLlanKKFwjfcNNoMXtm8LNbyh0rMbQN2XukQ==,iv:az2i0ldH75nHGah4DeOxaXmDbVYqmC1c77ptZqFA9BI=,tag:zoDdKj9bR7fgIDo1/dEU2g==,type:str]
sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxNWNmUzVNUGdWRnE0ZFpF\nM0JQZWZ3UDdEVzlwTmIxakxOZXBkT2x2ZlNrClRtV2M3S2daSGxUZmFDSWQ2Nmh4\neU51QndFcUxlSE00RFovOVJTcDZmUUUKLS0tIDcvL3hRMDRoMWZZSXljNzA3WG5o\nMWFic21MV0krMzlIaldBTVU0ZDdlTE0K7euGQtA+9lHNws+x7TMCArZamm9att96\nL8cXoUDWe5fNI5+M1bXReqVfNwPTwZsV6j/+ZtYKybklIzWz02Ex4A==\n-----END AGE ENCRYPTED FILE-----\n
sops_age__list_0__map_recipient=age1f5002gj4s78jju45jd28kuejtcfhn5cdujz885fl7z2p9ym68pnsgky87a
sops_lastmodified=2026-02-26T14:31:14Z
sops_mac=ENC[AES256_GCM,data:iqFuTexTS9U/Nv8xoTpHljTNQTGX9ITcJ3AjhDEtxrh0Z9/lngfBvGtjiKmpwFGlobQw/x+/YLM+u3MhciwXF7qNwFfJ/StN2Y66uF71SxWotbL70Dxl4oWSVL3sU+2NYbw5yP0p+xCbE+rEd5SqAe6K5yyq5X25hz8fIapxlYA=,iv:foqoWQVMipuOAQ0Kp799PaIhCIrxV8T5cC811wIzxR8=,tag:yNfxSV3R21XEXksjmdsKBw==,type:str]
sops_unencrypted_suffix=_unencrypted
sops_version=3.12.1