Booking integrity, bilingual i18n, SEO, and security/DB hardening#68
Conversation
…look) Phase 1 of the full UI redesign: - Design system in styles.css: teal brand + amber accent tokens, Plus Jakarta Sans, soft shadows, and reusable component classes (btn/btn-*, input, label, card, badge, navlink). - Branded sticky header (logo chip + wordmark, pill nav, account chip) and a real footer. - Landing: gradient hero, a floating search card with a 'More filters' disclosure, popular-route chips, a value-props strip, loading skeletons, a friendly empty state, and richer trip cards (route, seats-left badge, per-seat price). ng build + ng lint clean.
Fresh design language, not a reskin of the old layout: - New system: ink/midnight base, indigo-violet brand, amber pop; Space Grotesk display over Inter body; pill buttons, rounded-3xl cards, soft/glow shadows; a full-bleed helper. - New landing: full-bleed dark immersive hero with gradient orbs, a glass pill search bar, gradient popular-route cards, a feature trio, skeletons, empty state, and redesigned trip cards. This is phase 1; remaining screens (auth, booking journey, vendor, admin) will be rebuilt in the same language next.
…resh toast - body overflow-x-hidden so the full-bleed hero (100vw) no longer shows a horizontal scrollbar - landing now served at / (root); /search redirects to it; homeRoute + nav point at / - error interceptor skips the startup /auth/refresh 400 (no more 'Something went wrong' on cold load)
…ws marquee, CTA, footer) - Navbar merges seamlessly into the hero on the landing (dark sticky header, no white gap/split); solid white header elsewhere. Nav link colours inherit so they read on both. - Landing filled out: 'Most booked' trending routes (with a Hot badge), 'Why TPX' trio, an auto-scrolling reviews carousel (CSS marquee, pauses on hover, reduced-motion safe), and a full-bleed CTA band. - Real multi-column dark footer (brand + tagline, Explore/Why/Operators, bottom bar, star motif).
- add ThemeService (localStorage + system fallback) toggling a `.dark` class on <html>; theme toggle in the nav - apply dual-mode styling across auth, vendor, admin, account, tickets, booking and payment pages plus the shared component classes in styles.css - landing hero: static golden-hour image (hero.jpg) with the search over it - pin Microsoft.OpenApi 2.9.0 (security) in Directory.Packages.props
… indexes Money/integrity: tiered cancellation refunds, trip-cancel refunds to paid customers, webhook amount/currency verification + seat-collision/trip-status compensation, refund reconciliation worker, promo redemption inside the booking transaction, seat-count shrink guard, ghost-confirm status re-read, desk-cancel departure gate. Concurrent-cancel now returns a graceful 409, not a 500. Lifecycle features: no-show, seat-change, trip reschedule + manifest, admin refunds list/retry, GDPR self-delete. Auth/session: per-request lockout check (deleted/suspended -> immediate 401), token revocation on suspend and delete, refresh_token->user FK cascade, pinned JWT alg to HS256. Database: refund BookingId + pending-poll indexes, Booking.ContactPhone + CancellationReason, Trip actual departure/arrival, fleet/company compliance fields, data-retention worker for outbox + refresh tokens; two additive migrations (no data loss). SEO data API: /api/seo routes, route detail, cities, sitemap.xml + slug helper. Validation: added change-seat and reschedule validators; tightened promo fixed-amount cap and trip arrival-after-departure bounds.
…ing pages i18n: complete English/Arabic rollout for booking, payment, ticket, my-bookings, account, and every vendor + admin screen (436 keys, full parity), split into per-area dictionaries; widened translate pipe to accept piped values. SEO: static prerendering (SSG) via @angular/ssr, served by the existing nginx. New /routes, /bus/:route (city-pair landing), /city/:city pages with unique titles, canonical, OG/Twitter, BreadcrumbList/Product/FAQ JSON-LD and a search CTA. SeoService applies metadata to every route (noindex on private/auth/vendor/ admin pages); robots.txt; home "popular routes" internal links; nginx serves the prerendered page at the no-trailing-slash canonical URL and proxies /sitemap.xml. Made theme + translation services SSR-safe (DOCUMENT injection, platform guards). Booking: optional contact-phone input wired to create-booking. Auth: shared safe-return-path guard on the login redirect (open-redirect fix).
Integration: rewrote booking-cancellation tests for the tiered refund policy (full/half/none by time-to-departure), added seat-change and SEO API tests. E2E: Playwright golden flow (login -> search -> seat -> book -> pay -> ticket) against the full compose stack, with a self-resetting global setup. Load: k6 baseline (smoke + soak) script.
…w, hooks Pinned every GitHub Actions reference to a full commit SHA and tightened workflow token permissions (least privilege) to satisfy Scorecard. Added a dormant staging/dynamic workflow (E2E + ZAP + k6, gated on a STAGING_URL secret) and Semgrep SAST + Trivy image scan to CI. Added SECURITY.md, a commit-msg hook that strips AI attribution trailers, and gitignore entries for e2e artifacts and local compose overrides.
|
Important Review skippedToo many files! This PR contains 169 files, which is 19 over the limit of 150. To get a review, narrow the scope: Upgrade to a paid plan to raise the limit. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (10)
📒 Files selected for processing (169)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Dependency ReviewThe following issues were found:
|
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
- trivy-action v0.28.0's transitive setup-trivy@v0.2.1 tag was removed upstream, breaking the docker CVE-scan job at action-download; pin v0.36.0 instead. - Slug.IsValid: use LINQ .All (clears CodeQL missed-select). - Booking.Cancel: add an XML <summary> (clears CodeQL doc-comment alert). - nginx sitemap proxy: stop forwarding the client Host (pin an explicit upstream Host) so a spoofed Host header can't inject origins into sitemap URLs — the absolute <loc> URLs come from Seo:PublicBaseUrl (Semgrep request-host-used).
gsap carried a proprietary "no-charge standard" license that the dependency-review gate disallows, and it was dead weight — a leftover from the removed animation experiments with no imports in the source (only a stale CSS comment, now cleaned). Removing it clears the dependency-review license failure and trims the install.
The /routes, /bus/:route and /city/:city pages now render their visible body (H1, intro, FAQ, badges, CTAs, empty/not-found states) through the `t` pipe in English/Arabic (39 keys, full parity), matching the rest of the app. Prerendered HTML and all SEO metadata + JSON-LD stay English (server default), so crawler output is unchanged; Arabic renders on language toggle at runtime.
… pool The outbox publisher drained without a lock, so running >1 API instance would dispatch each domain-event side effect (e.g. a booking-confirmation email) once per instance. Added a Postgres advisory-lock leader guard (PgLeaderLock) so only one instance drains the outbox per tick; applied the same guard to the refund reconciliation worker (external gateway calls). The seat-hold sweeper and data-retention worker stay unguarded on purpose — they are idempotent set-based deletes, safe on every instance. Also bounded the per-instance Npgsql pool (Database:MaxPoolSize, default 20) so MaxPoolSize x instances stays under Postgres max_connections, and documented the rate limiter's per-instance behaviour + the scale-out moves in a readiness report (docs/audit/SCALABILITY-READINESS.md). Verified: 87 unit + 69 integration pass (the integration host runs the real workers, so the outbox drain is exercised under the new lock).
… sqli false-positive)
…uage
Verification, password-reset and booking-confirmation emails now render in the
recipient's stored language (RTL for Arabic), falling back to English when it's
unknown.
- User carries an optional Language ("en"/"ar"), captured at registration from
the SPA's active language (migration UserLanguage adds a nullable column to
AspNetUsers).
- EmailTemplates take a lang argument and emit MSA Arabic subject + body with
dir="rtl"; all HTML-escaping of interpolated values preserved.
- Language is resolved in the application handlers (which have IIdentityService)
and threaded to the send sites, keeping the singleton email service free of a
scoped captive dependency; the outbox looks the customer's language up by
email for booking-confirmation.
Backward-compatible: every new field/param is optional and defaults to English.
Verified: 87 unit + 69 integration pass.
Large hardening + feature release on top of the UI redesign branch. All changes verified locally: backend build 0 errors, 87 unit + 69 integration tests passing, frontend build clean, both new migrations apply to a fresh DB via the compose migrator, and the Playwright E2E golden flow (login → search → seat → book → pay → ticket) passes against the full stack.
Backend
refresh_token → userFK cascade, JWT algorithm pinned to HS256.Booking.ContactPhone+ cancellation reason, trip actual timestamps, fleet/company compliance fields, data-retention worker; two additive migrations (no data loss)./api/seoroutes, cities, sitemap.xml.Frontend
/routes,/bus/:route,/city/:citylanding pages with metadata, canonical, OG, and JSON-LD in the raw HTML; robots.txt; sitemap proxy;noindexon private pages; SSR-safe theme/i18n services.Tests / CI
STAGING_URLsecret.Follow-ups (need a deploy target / decision)
Seo:PublicBaseUrl+ the SPAsiteBaseUrl+ robotsSitemap:line to the real production origin at deploy (canonicals/OG depend on it).User.Languagecolumn).STAGING_URLis set.