From 05de7adbfa885448df05ca20a03f6dfd35146c8c Mon Sep 17 00:00:00 2001 From: omthorat2004 Date: Thu, 3 Sep 2026 09:48:19 -0700 Subject: [PATCH 1/4] fta: sample pr commit --- package-lock.json | 147 +++++++++++++++++++++++++++++---- packages/frontend/.env.example | 16 ++++ packages/frontend/.gitignore | 2 + packages/frontend/package.json | 1 + 4 files changed, 150 insertions(+), 16 deletions(-) create mode 100644 packages/frontend/.env.example diff --git a/package-lock.json b/package-lock.json index ceef8e3..8b70677 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2553,6 +2553,18 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/ajv": { "version": "6.15.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", @@ -2780,6 +2792,12 @@ "node": ">= 0.4" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -2806,6 +2824,18 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.20.0.tgz", + "integrity": "sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.16.0", + "form-data": "^4.0.6", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^2.1.0" + } + }, "node_modules/axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -2969,7 +2999,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -3078,6 +3107,18 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3178,7 +3219,6 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -3235,6 +3275,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -3262,7 +3311,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -3393,7 +3441,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3403,7 +3450,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3441,7 +3487,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -3454,7 +3499,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -4061,6 +4105,26 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -4077,11 +4141,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/form-data": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.4", + "mime-types": "^2.1.35" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4145,7 +4224,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -4170,7 +4248,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -4258,7 +4335,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4330,7 +4406,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4343,7 +4418,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -4359,7 +4433,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -4385,6 +4458,19 @@ "hermes-estree": "0.25.1" } }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -5421,7 +5507,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -5464,6 +5549,27 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", @@ -5550,7 +5656,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/nanoid": { @@ -6119,6 +6224,15 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -7451,6 +7565,7 @@ "@milo/styles": "*", "@milo/ui": "*", "@react-three/fiber": "^9.7.0", + "axios": "^1.20.0", "clsx": "^2.1.1", "lucide-react": "^0.545.0", "next": "16.3.0", diff --git a/packages/frontend/.env.example b/packages/frontend/.env.example new file mode 100644 index 0000000..ec35e96 --- /dev/null +++ b/packages/frontend/.env.example @@ -0,0 +1,16 @@ +# Base URL of the FastAPI backend, read by lib/axios.config.ts. +# +# NEXT_PUBLIC_ is required: this value is read in the browser, where only +# NEXT_PUBLIC_* vars exist. It is a public URL, not a secret. +# +# Whatever origin this app is served from must appear in the backend's +# CORS_ORIGINS, or every authenticated request fails a preflight that the +# browser reports to JavaScript as an indistinguishable network error. +NEXT_PUBLIC_API_URL=http://127.0.0.1:8000 + +# Optional server-only override, used when server components reach the backend +# over an internal address the browser cannot resolve. Ignored in the browser. +API_URL= + +# Request timeout in milliseconds. Defaults to 15000 when unset or unparseable. +NEXT_PUBLIC_API_TIMEOUT_MS=15000 diff --git a/packages/frontend/.gitignore b/packages/frontend/.gitignore index 5ef6a52..4fa696c 100644 --- a/packages/frontend/.gitignore +++ b/packages/frontend/.gitignore @@ -32,6 +32,8 @@ yarn-error.log* # env files (can opt-in for committing if needed) .env* +# ...except the documented template, as packages/landing and packages/backend do. +!.env.example # vercel .vercel diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 97cc64b..2df53a5 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -13,6 +13,7 @@ "@milo/styles": "*", "@milo/ui": "*", "@react-three/fiber": "^9.7.0", + "axios": "^1.20.0", "clsx": "^2.1.1", "lucide-react": "^0.545.0", "next": "16.3.0", From 2547eb891811bb5ece4b99ce18f43a9809f5281d Mon Sep 17 00:00:00 2001 From: omthorat2004 Date: Tue, 15 Sep 2026 18:56:15 -0700 Subject: [PATCH 2/4] fix: remove comments --- .claude/skills/fastapi-backend/SKILL.md | 20 ++++++++-- packages/backend/src/milo_backend/app.py | 4 +- .../backend/src/milo_backend/core/_cookies.py | 38 +++++++++---------- .../src/milo_backend/core/_database.py | 19 ++++------ .../frontend/src/app/(marketing)/layout.tsx | 7 ---- packages/frontend/src/app/globals.css | 8 ---- .../marketing/candidate-illustration.tsx | 38 +------------------ .../src/components/marketing/link-only.tsx | 8 ---- .../components/marketing/marketing-header.tsx | 9 ----- .../components/marketing/raw-story-scene.tsx | 37 +----------------- .../src/components/marketing/raw-story.tsx | 19 ---------- .../frontend/src/components/ui/button.tsx | 6 --- .../frontend/src/hooks/use-media-query.ts | 7 ---- packages/styles/globals.css | 10 ----- packages/ui/src/shipping-log/data.ts | 24 ------------ packages/ui/src/shipping-log/shipping-log.tsx | 22 +---------- 16 files changed, 48 insertions(+), 228 deletions(-) diff --git a/.claude/skills/fastapi-backend/SKILL.md b/.claude/skills/fastapi-backend/SKILL.md index c9f5de5..8501288 100644 --- a/.claude/skills/fastapi-backend/SKILL.md +++ b/.claude/skills/fastapi-backend/SKILL.md @@ -38,9 +38,23 @@ import block and `__all__`, keep that list alphabetical, ruff's isort rules will `get_settings()` is `@lru_cache`d. Never construct `Settings()` in application code, and never read `os.environ` directly. -Functions that need config take `settings: Settings | None = None` and fall back to `get_settings()` -inside the body. `_database.py`, `_cookies.py` and `_rate_limit.py` all do this. It is the seam that -lets a test pass a hand-built `Settings` without touching the cache. + +Also remember that all the variables we need need to add in settings and access from setting only. If any variable is not environment variable put that as a value in settings. + +A function takes config one of two ways, never both. `settings: Settings | None = None` with a +`settings or get_settings()` fallback is banned: it advertises an optional argument that only tests +ever pass, and leaves two names for one value in every body. + +1. **Required keyword argument**, `*, settings: Settings`, whenever our own code calls the function. + `set_auth_cookies`, `clear_auth_cookies` and `connect` are the examples. The function stays pure, + a test builds a `Settings(...)` and passes it, and nothing has to touch the `lru_cache`. Routes + receive it through `Depends(get_settings)` rather than plumbing it by hand. +2. **No parameter at all**, calling `get_settings()` in the body, only when option 1 is impossible: + the signature belongs to a framework (`client_key(request)` is invoked by slowapi), the call + happens at import (`build_limiter()`), or the function is already a global accessor and purity is + unreachable (`get_database()` reads the module-global client). + +When in doubt, option 1. Secrets are `SecretStr` and are read through the `jwt_secret` and `ip_salt` properties, which raise when unset. Do not call `.get_secret_value()` at a call site. diff --git a/packages/backend/src/milo_backend/app.py b/packages/backend/src/milo_backend/app.py index 92910d6..197ac7f 100644 --- a/packages/backend/src/milo_backend/app.py +++ b/packages/backend/src/milo_backend/app.py @@ -12,8 +12,8 @@ @asynccontextmanager -async def lifespan(app: FastAPI) -> AsyncGenerator[None,None]: - await connect() +async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: + await connect(get_settings()) try: yield finally: diff --git a/packages/backend/src/milo_backend/core/_cookies.py b/packages/backend/src/milo_backend/core/_cookies.py index bc979a0..d9e33cc 100644 --- a/packages/backend/src/milo_backend/core/_cookies.py +++ b/packages/backend/src/milo_backend/core/_cookies.py @@ -2,7 +2,7 @@ from starlette.responses import Response -from milo_backend.core._settings import Settings, get_settings +from milo_backend.core._settings import Settings ACCESS_TOKEN_COOKIE = "milo_access_token" REFRESH_TOKEN_COOKIE = "milo_refresh_token" @@ -13,31 +13,29 @@ def set_auth_cookies( *, access_token: str, refresh_token: str, - settings: Settings | None = None, + settings: Settings, refresh_path: str = "/", ) -> Response: - config = settings or get_settings() - response.set_cookie( key=ACCESS_TOKEN_COOKIE, value=access_token, - max_age=int(config.access_token_expiry.total_seconds()), + max_age=int(settings.access_token_expiry.total_seconds()), path="/", - domain=config.cookie_domain, - httponly=config.cookie_httponly, - secure=bool(config.cookie_secure), - samesite=config.cookie_samesite, + domain=settings.cookie_domain, + httponly=settings.cookie_httponly, + secure=bool(settings.cookie_secure), + samesite=settings.cookie_samesite, ) response.set_cookie( key=REFRESH_TOKEN_COOKIE, value=refresh_token, - max_age=int(config.refresh_token_expiry.total_seconds()), + max_age=int(settings.refresh_token_expiry.total_seconds()), path=refresh_path, - domain=config.cookie_domain, - httponly=config.cookie_httponly, - secure=bool(config.cookie_secure), - samesite=config.cookie_samesite, + domain=settings.cookie_domain, + httponly=settings.cookie_httponly, + secure=bool(settings.cookie_secure), + samesite=settings.cookie_samesite, ) return response @@ -46,19 +44,17 @@ def set_auth_cookies( def clear_auth_cookies( response: Response, *, - settings: Settings | None = None, + settings: Settings, refresh_path: str = "/", ) -> Response: - config = settings or get_settings() - for key, path in ((ACCESS_TOKEN_COOKIE, "/"), (REFRESH_TOKEN_COOKIE, refresh_path)): response.delete_cookie( key=key, path=path, - domain=config.cookie_domain, - httponly=config.cookie_httponly, - secure=bool(config.cookie_secure), - samesite=config.cookie_samesite, + domain=settings.cookie_domain, + httponly=settings.cookie_httponly, + secure=bool(settings.cookie_secure), + samesite=settings.cookie_samesite, ) return response diff --git a/packages/backend/src/milo_backend/core/_database.py b/packages/backend/src/milo_backend/core/_database.py index 606a709..1d3e61e 100644 --- a/packages/backend/src/milo_backend/core/_database.py +++ b/packages/backend/src/milo_backend/core/_database.py @@ -12,20 +12,19 @@ _client: AsyncIOMotorClient[dict[str, Any]] | None = None -async def connect(settings: Settings | None = None) -> None: +async def connect(settings: Settings) -> None: global _client - config = settings or get_settings() _client = AsyncIOMotorClient( - config.mongodb_uri, - serverSelectionTimeoutMS=config.mongodb_timeout_ms, - connectTimeoutMS=config.mongodb_timeout_ms, + settings.mongodb_uri, + serverSelectionTimeoutMS=settings.mongodb_timeout_ms, + connectTimeoutMS=settings.mongodb_timeout_ms, maxPoolSize=10, retryWrites=True, ) await _client.admin.command("ping") - logger.info("Connected to MongoDB database %s", config.mongodb_db) + logger.info("Connected to MongoDB database %s", settings.mongodb_db) async def disconnect() -> None: @@ -43,8 +42,6 @@ def get_client() -> AsyncIOMotorClient[dict[str, Any]]: return _client -def get_database( - settings: Settings | None = None, -) -> AsyncIOMotorDatabase[dict[str, Any]]: - config = settings or get_settings() - return get_client()[config.mongodb_db] +def get_database() -> AsyncIOMotorDatabase[dict[str, Any]]: + settings = get_settings() + return get_client()[settings.mongodb_db] diff --git a/packages/frontend/src/app/(marketing)/layout.tsx b/packages/frontend/src/app/(marketing)/layout.tsx index a1a1e90..e9a5200 100644 --- a/packages/frontend/src/app/(marketing)/layout.tsx +++ b/packages/frontend/src/app/(marketing)/layout.tsx @@ -1,13 +1,6 @@ import { MarketingFooter } from "@/components/marketing/marketing-footer"; import { MarketingHeader } from "@/components/marketing/marketing-header"; -/** - * Shell for every public, unauthenticated page. - * - * A route group, so these pages sit at /features and /path rather than - * /marketing/features. The authenticated app will get its own group and its own - * chrome without inheriting any of this. - */ export default function MarketingLayout({ children }: { children: React.ReactNode }) { return (
diff --git a/packages/frontend/src/app/globals.css b/packages/frontend/src/app/globals.css index f9077a1..1ae5347 100644 --- a/packages/frontend/src/app/globals.css +++ b/packages/frontend/src/app/globals.css @@ -1,11 +1,3 @@ -/* - * Entry stylesheet for the product app. - * - * Tokens and base styles live in packages/styles/globals.css so every Milo app - * shares one palette. Only the source globs are app-specific: Tailwind's - * automatic content detection resolves relative to the imported file, which - * would point into node_modules rather than at this app. - */ @import "@milo/styles/globals.css"; @source "../../src"; diff --git a/packages/frontend/src/components/marketing/candidate-illustration.tsx b/packages/frontend/src/components/marketing/candidate-illustration.tsx index 0d57452..9c87e07 100644 --- a/packages/frontend/src/components/marketing/candidate-illustration.tsx +++ b/packages/frontend/src/components/marketing/candidate-illustration.tsx @@ -2,32 +2,15 @@ import Image from "next/image"; import { cn } from "@/lib/utils"; -/** - * Aarav at his laptop, with the current beat played out around him. - * - * The figure itself is a professionally drawn unDraw illustration, recoloured - * to the Milo palette, rather than paths written by hand. Hand-authored bezier - * coordinates do not produce a convincing human, and the earlier attempt at one - * proved it. - * - * What is authored here is the motion: applications leaving the laptop, and the - * single signal that eventually comes back. Those are the parts that carry the - * argument, and they have to be driven by the story state. - */ - export type CandidatePose = "typing" | "waiting" | "slumped" | "signal"; type Props = { pose: CandidatePose; - /** - * Increments on every application sent. Used as a React key so the paper - * animation restarts rather than playing once and stopping. - */ + sendCount: number; className?: string; }; -/** How present the scene feels, per beat. Waiting and slumping dim it. */ const sceneOpacity: Record = { typing: 1, waiting: 0.78, @@ -35,13 +18,6 @@ const sceneOpacity: Record = { signal: 1, }; -/** - * Whole-figure motion, per beat. - * - * The illustration is a flat asset, so its internals cannot be posed. Moving - * the figure as a unit still reads clearly: working, waiting, sinking, then - * lifting when something finally comes back. - */ const figureMotion: Record = { typing: "animate-typing-bob", waiting: "animate-breathe", @@ -59,8 +35,6 @@ const figureTransform: Record = { export function CandidateIllustration({ pose, sendCount, className }: Props) { return (
- {/* Outer element carries the pose, inner one the looping motion, so the - two transforms never fight over the same property. */}
- {/* Motion layer, sized to the same box so coordinates line up. */}