Minor changes#30
Merged
Merged
Conversation
Adds Phase 3b to the seed script: downloads a crop-appropriate Unsplash image for each listing and uploads it via the existing multipart endpoint (Cloudinary). Blog posts now get per-post cover images instead of one shared placeholder. Both phases fail gracefully so the rest of the seed continues if Cloudinary is not configured or a download times out.
Adds POST /listings/{id}/images/url (INTERNAL_SECRET-gated) that stores
an external URL directly in listing_images with public_id=null. The
existing Cloudinary upload path for real users is completely untouched.
Seed Phase 3b now calls this endpoint with crop-matched Unsplash URLs
instead of downloading and re-uploading through Cloudinary.
Seed interactions (orders, messages) generate notification rows for seeded users. destroy_seed was missing the notification_db step, leaving orphaned rows after teardown. Added destroy_notifications() targeting user_id IN seeded IDs and wired it between destroy_messages and destroy_payments.
Authlib's session-backed state storage was unreliable behind the nginx + CloudFront proxy chain — the session cookie was not surviving the login→Google→callback roundtrip, causing a MismatchingStateError on every Google OAuth attempt. New approach: generate a cryptographically random state on /google/login, store it in a short-lived _oauth_state httpOnly cookie (same pattern as setup_token which already works), and validate it on the callback. Code exchange is done directly via httpx against Google's token and userinfo endpoints, removing the authlib session dependency entirely. Also fixes the returning-user redirect: complete-profile users now go to /home instead of back to the profile form, and incomplete-profile returning users get a fresh setup_token.
The _oauth_state cookie set on the /google/login 302 redirect was also being dropped before reaching the browser (same CloudFront/nginx issue as the original session cookie). No cookie or session can be reliably set on a redirect response in this proxy chain. New approach: embed the CSRF state directly in the state parameter as a URLSafeTimedSerializer-signed token (itsdangerous, already a dep). The state is self-verifiable on the callback — no storage of any kind needed. 5-minute expiry enforced by itsdangerous timestamp.
Was calling /users on the user service which doesn't exist — the internal create_user route is at POST / (no prefix). Password registration already used the correct URL (USER_SERVICE_URL/).
CloudFront's /auth/complete-profile behavior was targeting S3 with GET/HEAD only — POST from the profile form was blocked at the CDN layer, returning 403/405, never reaching the auth service. Change the behavior to target EC2 with all methods allowed. Add a GET handler in the auth service that returns 404 so CloudFront's custom_error_response still serves index.html for SPA page loads.
Brings in bot_auth Redis relay, Google OAuth returning-user fix (redirect to /auth/google/callback?access_token=...), docker-compose profile gating for optional services, and PESAPAL_SANDBOX rename. Conflict in oauth.py resolved by taking origin/main's returning-user handling (both complete and incomplete profile paths).
…h/google/callback /auth/google/callback matches the CloudFront /auth/* → EC2 behavior, so the browser would loop back to the backend callback handler with no state param, causing the 'Invalid OAuth state' error. /auth/sign-in is explicitly routed to S3 so the SPA loads and loginWithToken can run.
…teway deps Both stacks declare soko-ml-bridge as external but nothing created it, causing docker compose up to fail silently. Add explicit network create step (idempotent) before both compose invocations. Also relax ml-gateway-service depends_on from service_healthy to service_started so the gateway starts even if an individual ML service is slow to pass health checks, with restart:unless-stopped handling retries.
int(None) crashed before the try/except block when quantity_kg is not provided. Farmers without listings send no quantity, so the backend must tolerate None. Use quantity or 0 as the cache key slot so null-quantity requests still get routed (Tier 2/3 generic response).
Add POST /auth/alert/unsupported-crop endpoint to the auth service. When a farmer's specialty or listing falls outside ML crop coverage, the frontend calls this endpoint which sends a SendGrid email to andrewssuubi@gmail.com listing the unsupported crop names and user ID. Endpoint is JWT-protected and silently no-ops when SendGrid is not configured.
The inline environment: value overrode the BOT_SECRET loaded from Secrets Manager via env_file, so the real secret was never used. Removing it lets the env_file value take effect.
fetch-secrets.sh was writing only INTERNAL_SECRET for produce and blog, leaving CLOUDINARY_CLOUD_NAME, CLOUDINARY_API_KEY, and CLOUDINARY_API_SECRET unset. Both services declare these as required fields in their Settings class, so they crashed on startup in production — causing the marketplace 502.
…lth timing - location-service now waits for db-init to complete before starting, preventing a race where market_registry table may not exist on fresh deploys - fix hardcoded fallback port in market_router.py (8080 -> 8000) - increase deploy health check sleep from 15s to 90s so ML stack status is accurate in CI logs (Kafka needs ~90s to become healthy)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixed a few merge conflicts to ensure all changes work as intended