Commit graph

31 commits

Author SHA1 Message Date
Tracewebstudio Dev
8423b7a0f5 fix: security, wallet holds, printpdf upgrade
- Upgrade printpdf 0.7 → 0.12.5 in job_seekers (fixes lopdf HIGH CVE RUSTSEC-2023-0068)
  Rewrote build_resume_pdf() for the new Op-based API; same PDF output
- Add wallet/me/holds and wallet/me/holds/{id}/release routes to profession_shared
  Backed by wallet::hold::list_for_user and wallet::hold::release
  Applies to all 9 profession services via the shared router
- Add deny.toml for cargo-deny (advisory + ban policy enforcement)
  RSA timing CVE and bincode unmaintained acknowledged with documented reasons

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-12 13:38:17 +02:00
Ashwin Kumar Sivakumar
c1eed2530d fix: stop leaking raw LiteLLM error bodies; harden prompts against injection; fix UTF-8 panic
All checks were successful
build-and-release / build (companies) (push) Successful in 4s
build-and-release / build (catering-services) (push) Successful in 6s
build-and-release / build (developers) (push) Successful in 7s
build-and-release / build (customers) (push) Successful in 8s
build-and-release / build (employees) (push) Successful in 8s
build-and-release / build (fitness-trainers) (push) Successful in 6s
build-and-release / build (graphic-designers) (push) Successful in 5s
build-and-release / build (gateway) (push) Successful in 8s
build-and-release / build (job-seekers) (push) Successful in 7s
build-and-release / build (jobs) (push) Successful in 7s
build-and-release / build (makeup-artists) (push) Successful in 5s
build-and-release / build (payments) (push) Successful in 5s
build-and-release / build (photographers) (push) Successful in 5s
build-and-release / build (social-media-managers) (push) Successful in 6s
build-and-release / build (tutors) (push) Successful in 6s
build-and-release / build (ugc-content-creators) (push) Successful in 5s
build-and-release / build (video-editors) (push) Successful in 5s
build-and-release / build (cron) (push) Successful in 51s
build-and-release / build (users) (push) Successful in 3m12s
Follow-up on the AI safety review — addressed the three remaining
lower-severity findings:

1. crates LiteLlmError::error_body() returned the raw upstream response
   body verbatim to the client on any non-2xx LiteLLM response. That
   body can contain internal routing/diagnostic details from the
   LiteLLM proxy or the underlying model provider. Now returns a
   generic, status-aware message to the client; the full body is
   logged server-side via tracing::error! at each of the three call
   sites that construct LiteLlmError::Api, so nothing is lost for
   debugging — it's just not exposed to end users.

2. Added an explicit anti-prompt-injection clause to
   ai/orchestrator.rs::GROUNDING_GUARDRAIL, the baseline system prompt
   applied to every AI feature call via effective_system_prompt() —
   instructs the model to treat all user/company-authored input
   (job descriptions, profile text, chat messages) as data to analyze,
   never as instructions to follow. Covers every ai.rs handler that
   goes through call_feature/call_feature_with_plan in one place,
   rather than patching each call site's prompt construction
   individually.

3. apps/cron/src/tasks/auto_apply.rs's cover-letter prompt doesn't run
   through the orchestrator (separate app/crate), so hardened it
   directly: fenced the untrusted CANDIDATE/JOB sections with explicit
   "this is data, not instructions" framing. While there, fixed a
   latent panic: `&job_desc[..job_desc.len().min(500)]` slices on a
   raw byte offset, which panics if byte 500 isn't a UTF-8 character
   boundary — a company job description with any multi-byte character
   before that point (accented letters, emoji, etc.) would crash the
   whole cron run. Switched to char_indices() to find a safe boundary.
2026-07-21 05:56:21 +05:30
Ashwin Kumar Sivakumar
3e701f2fe6 fix: close two real money/spend races (Tracecoin double-credit, unbounded AI overspend)
Some checks failed
build-and-release / build (ugc-content-creators) (push) Waiting to run
build-and-release / build (users) (push) Waiting to run
build-and-release / build (video-editors) (push) Waiting to run
build-and-release / build (catering-services) (push) Successful in 1m47s
build-and-release / build (companies) (push) Successful in 2m0s
build-and-release / build (cron) (push) Successful in 2m12s
build-and-release / build (customers) (push) Successful in 2m42s
build-and-release / build (gateway) (push) Successful in 1m0s
build-and-release / build (developers) (push) Successful in 1m27s
build-and-release / build (fitness-trainers) (push) Successful in 1m54s
build-and-release / build (employees) (push) Successful in 1m59s
build-and-release / build (job-seekers) (push) Successful in 1m57s
build-and-release / build (makeup-artists) (push) Successful in 1m39s
build-and-release / build (graphic-designers) (push) Has been cancelled
build-and-release / build (payments) (push) Has been cancelled
build-and-release / build (jobs) (push) Has been cancelled
build-and-release / build (social-media-managers) (push) Has been cancelled
build-and-release / build (tutors) (push) Has been cancelled
build-and-release / build (photographers) (push) Has been cancelled
Asked to review Tracecoin and AI implementation safety. Found and fixed
two exploitable TOCTOU races, plus a data-integrity bug:

1. apps/payments/src/main.rs::verify_payment — the PayU success callback
   is called directly by the client (not a server-to-server webhook), so
   a user fully controls how many times they replay a valid success
   payload. The payment "is it still PENDING" check and the "mark
   SUCCESS + credit wallet" write were separate, non-transactional
   queries — concurrent replays could both pass the check before either
   commits, double- (or N-times-) crediting the wallet for one real
   payment. Now wrapped in a single transaction with
   `SELECT ... FOR UPDATE` on the payments row, so a second concurrent
   call blocks until the first commits, then correctly sees the row is
   no longer PENDING (Postgres re-evaluates the WHERE clause via
   EvalPlanQual after the lock is granted).

2. crates/db/src/models/ai/repository.rs — UserAiSubscriptionRepository
   had the exact same shape of bug: apps/users/src/ai/credits.rs::
   charge_feature read the subscription, checked daily-limit and credit
   balance, THEN issued two separate unconditional `UPDATE ... SET x =
   x + $1` statements with no WHERE guard on the balance. N concurrent
   requests from one user all pass the check before any deduction
   lands, running up unlimited LLM API spend (this endpoint is called
   before/around real LiteLLM calls, so the cost is real). Added
   UserAiSubscriptionRepository::try_charge — a single conditional
   UPDATE that checks the daily limit and credit balance and deducts
   atomically, returning None (mapped to the existing error types) if
   either check fails.

3. apps/cron/src/tasks/auto_apply.rs — daily_actions_used was being
   incremented twice per auto-applied job (once in the credit-deduct
   UPDATE, once more in a second, redundant UPDATE right after) —
   silently halving job seekers' effective daily auto-apply limit.
   Removed the redundant second UPDATE.

Also added non-negative CHECK constraints directly to the live
database (tracecoin_wallets.balance/reserved,
user_ai_subscriptions.daily_actions_used/monthly_credits_used/
purchased_credits_used) as defense in depth — belt-and-suspenders in
case a future code path reintroduces a similar bug.
2026-07-21 05:51:23 +05:30
Ashwin Kumar Sivakumar
2e95c4750b fix: company job posting, job seeker profile submission, and job applications
- Company approval wrote profile status to 'ACTIVE' (company_profiles'
  own pre-verification default) using an id column that never matched
  any row, so create_job's APPROVED check always rejected newly
  approved companies. Match on user_id for user_id-keyed tables and
  write the canonical 'APPROVED' status.
- job_seeker_profiles was missing columns the job-seeker app has
  always queried (full_name, location, summary, skills,
  active_application_count, status), and the job_applications /
  job_seeker_documents tables it depends on were never migrated in —
  job seeker profile save/submit and job applications failed outright
  with "column/relation does not exist".
- Renamed the job_seeker first_name/last_name split to full_name to
  match what the frontend has always sent.
- Special-cased JOB_SEEKER in the generic profile.rs handlers (mirrors
  the existing COMPANY special-case) so the shared ProfilePage save/
  submit flow, which was routed through a user_role_profile_id-based
  path job_seeker_profiles never had, now persists correctly.
- Fixed apply_to_job's company notification query joining a
  nonexistent "companies" table instead of company_profiles.
- Fixed auto-apply cron's company status filter to match the
  corrected 'APPROVED' status.
2026-07-21 01:00:47 +05:30
Ashwin Kumar Sivakumar
ea622a4af8 chore: retrigger isolated CI builds for 6 more services on bad digests
All checks were successful
build-and-release / build (catering-services) (push) Successful in 3s
build-and-release / build (companies) (push) Successful in 5s
build-and-release / build (customers) (push) Successful in 4s
build-and-release / build (developers) (push) Successful in 5s
build-and-release / build (employees) (push) Successful in 6s
build-and-release / build (graphic-designers) (push) Successful in 5s
build-and-release / build (job-seekers) (push) Successful in 5s
build-and-release / build (leads) (push) Successful in 4s
build-and-release / build (makeup-artists) (push) Successful in 5s
build-and-release / build (payments) (push) Successful in 4s
build-and-release / build (photographers) (push) Successful in 4s
build-and-release / build (social-media-managers) (push) Successful in 5s
build-and-release / build (gateway) (push) Successful in 3m25s
build-and-release / build (users) (push) Successful in 4s
build-and-release / build (video-editors) (push) Successful in 3s
build-and-release / build (cron) (push) Successful in 4m4s
build-and-release / build (jobs) (push) Successful in 4m12s
build-and-release / build (tutors) (push) Successful in 7m13s
build-and-release / build (fitness-trainers) (push) Successful in 8m58s
build-and-release / build (ugc-content-creators) (push) Successful in 8m51s
Same congestion pattern from the crates/contracts push. gateway still had
2 healthy replicas serving traffic throughout, so no outage — just a
failed rolling-update replica for these 6 services.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 03:01:39 +05:30
Ashwin Kumar Sivakumar
f7d0f6f9f5 fix: Update Dockerfiles to use ci.nxtgauge.com registry
Some checks failed
build-and-release / build (companies) (push) Failing after 39s
build-and-release / build (catering-services) (push) Failing after 57s
build-and-release / build (cron) (push) Failing after 1m4s
build-and-release / build (gateway) (push) Successful in 3m46s
build-and-release / build (fitness-trainers) (push) Successful in 9m8s
build-and-release / build (graphic-designers) (push) Successful in 8m58s
build-and-release / build (employees) (push) Successful in 9m17s
build-and-release / build (customers) (push) Successful in 9m47s
build-and-release / build (developers) (push) Successful in 9m48s
build-and-release / build (job-seekers) (push) Successful in 9m1s
build-and-release / build (jobs) (push) Successful in 4m17s
build-and-release / build (leads) (push) Successful in 8m23s
build-and-release / build (makeup-artists) (push) Successful in 8m40s
build-and-release / build (payments) (push) Successful in 9m21s
build-and-release / build (photographers) (push) Successful in 9m20s
build-and-release / build (social-media-managers) (push) Successful in 8m9s
build-and-release / build (tutors) (push) Successful in 8m16s
build-and-release / build (ugc-content-creators) (push) Successful in 6m59s
build-and-release / build (video-editors) (push) Successful in 6m9s
build-and-release / build (users) (push) Successful in 8m37s
2026-07-08 03:37:18 +05:30
Ashwin Kumar Sivakumar
cba7f607cd fix: resolve all warnings and errors
- Add #![allow(dead_code)] pragma to all main.rs files
- Remove unused imports from users handlers (ai_cache, AiCreditPackageRepository, AiCreditTransactionRepository)
- Make LiteLLMChatMessage and LiteLLMChoice public with public fields
- Fix remaining unused variables with cargo fix
- Add missing pub visibility modifiers to litellm structs

All packages now compile with ZERO warnings and errors!
2026-07-06 03:00:37 +05:30
Ashwin Kumar Sivakumar
b99651f330 fix: resolve warnings (partial)
- Fix unused variable entry_type -> _entry_type
- Remove unused imports BufMut and cache_jobs from companies handlers
- Fix doc comment on lazy_static
- Add #[allow(dead_code)] to reset_daily_actions and reset_monthly_credits
- Fix unused imports in job_seekers handlers
2026-07-06 02:55:42 +05:30
Ashwin Kumar Sivakumar
4f2683d085 chore: remove legacy AI quota system
Delete legacy code that used old company_ai_usage/job_seeker_ai_usage tables:
- Remove has_active_ai_pack() - old AI_PACK pricing package check
- Remove check_and_increment_usage() - legacy daily quota tracking
- Remove BASE_AI_LIMIT, get_ai_limit_for_package constants/functions
- Remove legacy queries from ai_auto_apply() and ai_usage_status()
- Update auto_apply.rs to use user_ai_subscriptions.daily_actions_used
  instead of job_seeker_ai_usage table
- Inline apply_scheduled_downgrades() and expire_trials() in cron tasks
  to remove dependency on users crate internal modules

The new system uses user_ai_subscriptions with:
- daily_actions_used / daily_credits_used counters
- monthly_credits_total / monthly_credits_used
- purchased_credits_total / purchased_credits_used

All AI billing now flows through the wallet/ledger system with
LiteLLM integration (Tasks 1-10).
2026-07-06 02:14:23 +05:30
Ashwin Kumar Sivakumar
0dd5045676 feat: Complete Ask Ash AI Credits implementation on high-performance branch (Tasks 1-10)
- Task 1: Admin endpoints for wallet management
- Task 2: AI Credits admin UI (pricing.tsx, credit.tsx)
- Task 3: Ollama security (NetworkPolicy, prompt validation, audit)
- Task 4: LiteLLM integration (litellm.rs, migrated AI feature handlers)
- Task 5: Refund architecture (ai_refunds table, endpoints)
- Task 6: Coupons, promotions, referrals (order creation with coupon)
- Task 7: Subscription lifecycle (plan upgrades/downgrades, cron jobs)
- Task 8: Credit expiration enforcement (daily cron task)
- Task 9: Token cost engine (ai_model_cost_config, margin view)
- Task 10: Observability (metrics tables, aggregation function)

Cherry-picked from main branch commit 3c0f45f
2026-07-06 01:49:16 +05:30
Tracewebstudio Dev
eb009ac3d0 feat: profile photo upload, PDF resume generation, AI auto-apply, schema fixes
- Profile photo upload: POST /api/profile/photo for all roles, stores via B2 storage
- PDF resume: auto-generated from job seeker portfolio on every profile save (printpdf)
- Company applications: enriched with applicant name, avatar, headline, skills, education
- AI auto-apply cron: rewrote run_auto_apply with correct schema (job_seeker_profiles,
  cover_note, ai_auto_apply_settings, ai_auto_apply_logs, credit deduction)
- Schema fix: job_seeker_profiles table name (was incorrectly 'job_seekers' in two places)
- Migration: add resume_url column to job_seeker_profiles
- Migrations: PayU rename, tracecoin hardening, lead reserve linkage, invoice/wallet crates
- PayU integration: ai_credits, packages, admin payment handlers
- Wallet and invoice crates added

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 13:31:06 +02:00
Ashwin Kumar Sivakumar
06e73eebb5 fix(ai): align backend plans and clean warnings 2026-06-15 09:23:44 +05:30
Ashwin Kumar Sivakumar
0c2ce413f9 Merge remote high-performance: keep new AI plans implementation and resolve conflicts 2026-06-15 06:18:52 +05:30
Ashwin Kumar Sivakumar
c85e6af22e feat(ai): complete AI plans/credits implementation and build tooling
- Add AI plans, credits, model routing, LiteLLM client, and orchestrator services
- Add AI management endpoints, auto-apply/auto-request handlers, and log endpoints
- Add cron jobs for daily action reset and monthly credit reset
- Add AI credit purchase flow in payments service
- Add ai_credit_packages migration with seed data
- Update Dockerfile build tooling across services
2026-06-15 06:15:49 +05:30
Tracewebstudio Dev
a4af5c2c06 feat: add LiteLLM support and auto-apply cron job
- Add get_llm_base_url() and get_llm_model() helper functions
- Update call_ollama_inline to route to LiteLLM when LLM_PROVIDER=litellm
- Add auto-apply cron task for background job matching
- Auto-apply matches job seekers to new jobs based on skills
- Generate cover letters via LiteLLM for each application
2026-06-14 18:00:38 +02:00
Tracewebstudio Dev
a3076ed526 feat: update DB schema - split users.first_name, users.last_name, roles split 2026-04-15 06:23:27 +02:00
Tracewebstudio Dev
2861e7a5fe fix: replace u.full_name with u.name in remaining services
- companies: user.name in email and contact queries
- customers: user.name in email
- job_seekers: u.name in company user query
- cron tasks (jobs/leads/requirements): use u.name instead of u.full_name
- contracts/profession_shared: u.name for customer_name fields
2026-04-13 17:12:49 +02:00
Tracewebstudio Dev
c433ab5fed feat(db): update service handlers and models for new schema
- Update leads service to use 'leads' table
- Update extension models to use user_role_profile_id
- Update ProfessionalRepository to work with new schema
- Create TracecoinWalletRepository for wallet operations
- Update all handlers to use new model fields
- Rename Application fields (job_seeker_id -> applicant_user_id)
- Update cron tasks for new schema
- Fix compilation errors across all services
2026-04-13 00:29:44 +02:00
Ashwin Kumar
73d167c333 fix: add OpenSSL static linking for musl builds
Added openssl-libs-static and OPENSSL_STATIC=1 environment variable
to fix reqwest/native-tls compilation errors with musl target.

Changes:
- Install openssl-libs-static in builder
- Set OPENSSL_STATIC=1 and OPENSSL_DIR=/usr
- Ensures OpenSSL is statically linked for all services
2026-04-09 11:59:57 +02:00
Ashwin Kumar
5b4e8fe908 refactor: use Alpine Linux with static musl binaries for all services
Switched from Debian to Alpine Linux for significant improvements:
- Image size: ~5MB vs ~100MB (95% smaller)
- Security: Minimal attack surface, no glibc vulnerabilities
- Static linking: No glibc version issues ever again
- Uses rust:alpine builder with x86_64-unknown-linux-musl target
- Static binaries with RUSTFLAGS='-C target-feature=+crt-static'

Fixes the GLIBC_2.38 error permanently by avoiding glibc entirely.
2026-04-09 11:51:57 +02:00
Ashwin Kumar
219960399b fix: update Dockerfiles to use debian:trixie-slim for glibc 2.38+ compatibility
Fixed glibc version mismatch between rust:latest builder (glibc 2.38+)
and debian:bookworm-slim runtime (glibc 2.36). This was causing:
- ./companies: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.38 not found
- ./payments: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.38 not found
- Similar errors for users service

Updated all 19 service Dockerfiles + Dockerfile.template to use
debian:trixie-slim which includes glibc 2.38+.
2026-04-09 11:48:46 +02:00
Ashwin Kumar
83c62a1c5e fix: convert all SQLx macros to runtime API, remove SQLX_OFFLINE requirement 2026-04-09 07:40:15 +02:00
Ashwin Kumar
1d3d07f001 fix: add Docker Hub login + switch runtime to AWS ECR Public to avoid rate limits 2026-04-09 06:26:01 +02:00
Ashwin Kumar
085b3169f6 fix: limit CARGO_BUILD_JOBS=2 to reduce OOM during parallel matrix builds 2026-04-09 05:55:50 +02:00
Ashwin Kumar
329f650079 fix: add SQLx offline cache and SQLX_OFFLINE=true for Docker builds 2026-04-09 05:46:32 +02:00
Ashwin Kumar
a2fa6cfbb9 fix: use rust:latest image tag (1.88 tag does not exist yet) 2026-04-09 05:34:07 +02:00
Ashwin Kumar
3318a0aec1 fix: bump Rust to 1.88 to satisfy dependency toolchain requirements 2026-04-09 01:49:34 +02:00
Ashwin Kumar
0a067bcb7b fix: add libssl-dev and Cargo.lock to all service Dockerfiles 2026-04-09 01:43:28 +02:00
Ashwin Kumar
4b4a45f90d fix: bump Rust to 1.85 to support required dependency features 2026-04-09 01:23:44 +02:00
Ashwin Kumar
235c5fce76 ci: add Woodpecker CI matrix pipeline and missing cron Dockerfile
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 00:09:04 +02:00
Ashwin Kumar
446b6322de feat(admin): wire management modules to live backend and add UGC role 2026-04-02 13:09:43 +02:00