@@ -17,18 +17,22 @@ defmodule Algora.Jobs do
17
17
18
18
def list_jobs ( opts \\ [ ] ) do
19
19
JobPosting
20
- |> order_by ( [ j ] , desc: j . inserted_at )
21
- |> maybe_filter_by_user ( opts [ :user_id ] )
20
+ |> apply_ordering ( opts )
21
+ |> maybe_filter_by_user ( opts )
22
+ |> join ( :inner , [ j ] , u in User , on: u . id == j . user_id )
23
+ |> maybe_filter_by_users ( opts [ :handles ] )
22
24
|> maybe_filter_by_tech_stack ( opts [ :tech_stack ] )
23
25
|> maybe_limit ( opts [ :limit ] )
24
26
|> Repo . all ( )
25
- |> Repo . preload ( :user )
27
+ |> apply_preloads ( opts )
26
28
end
27
29
28
30
def count_jobs ( opts \\ [ ] ) do
29
31
JobPosting
30
32
|> order_by ( [ j ] , desc: j . inserted_at )
31
- |> maybe_filter_by_user ( opts [ :user_id ] )
33
+ |> maybe_filter_by_user ( opts )
34
+ |> join ( :inner , [ j ] , u in User , on: u . id == j . user_id )
35
+ |> maybe_filter_by_users ( opts [ :handles ] )
32
36
|> maybe_filter_by_tech_stack ( opts [ :tech_stack ] )
33
37
|> Repo . aggregate ( :count )
34
38
end
@@ -39,12 +43,30 @@ defmodule Algora.Jobs do
39
43
|> Repo . insert ( )
40
44
end
41
45
42
- defp maybe_filter_by_user ( query , nil ) , do: where ( query , [ j ] , j . status in [ :active ] )
46
+ defp maybe_filter_by_user ( query , user_id: user_id , handles: handles ) when is_nil ( user_id ) and is_nil ( handles ) do
47
+ where ( query , [ j , u ] , j . status in [ :active ] )
48
+ end
43
49
44
- defp maybe_filter_by_user ( query , user_id ) do
50
+ defp maybe_filter_by_user ( query , user_id: user_id ) do
45
51
where ( query , [ j ] , j . user_id == ^ user_id and j . status in [ :active , :processing ] )
46
52
end
47
53
54
+ defp maybe_filter_by_user ( query , _ ) , do: query
55
+
56
+ defp maybe_filter_by_users ( query , nil ) , do: query
57
+
58
+ defp maybe_filter_by_users ( query , handles ) do
59
+ # Need to handle different query structures based on joins
60
+ case query . joins do
61
+ # When we have interview join, the user table is the 3rd binding ([j, i, u])
62
+ [ _interview_join , _user_join ] -> where ( query , [ j , i , u ] , u . provider_login in ^ handles )
63
+ # When we only have user join, it's the 2nd binding ([j, u])
64
+ [ _user_join ] -> where ( query , [ j , u ] , u . provider_login in ^ handles )
65
+ # No joins yet, will be added later
66
+ [ ] -> where ( query , [ j , u ] , u . provider_login in ^ handles )
67
+ end
68
+ end
69
+
48
70
defp maybe_filter_by_tech_stack ( query , nil ) , do: query
49
71
defp maybe_filter_by_tech_stack ( query , [ ] ) , do: query
50
72
@@ -55,6 +77,27 @@ defmodule Algora.Jobs do
55
77
defp maybe_limit ( query , nil ) , do: query
56
78
defp maybe_limit ( query , limit ) , do: limit ( query , ^ limit )
57
79
80
+ defp apply_ordering ( query , opts ) do
81
+ case opts [ :order_by ] do
82
+ :last_interview_desc ->
83
+ # Sort by most recent interview, then by job posting date
84
+ # Use COALESCE to handle NULL values for jobs without interviews
85
+ query
86
+ |> join ( :left , [ j ] , i in "job_interviews" , on: i . job_posting_id == j . id )
87
+ |> group_by ( [ j ] , [ j . id , j . inserted_at ] )
88
+ |> order_by ( [ j , i ] , [ desc: coalesce ( max ( i . inserted_at ) , j . inserted_at ) , desc: j . inserted_at ] )
89
+
90
+ _ ->
91
+ # Default ordering by job posting date
92
+ order_by ( query , [ j ] , desc: j . inserted_at )
93
+ end
94
+ end
95
+
96
+ defp apply_preloads ( jobs , opts ) do
97
+ preloads = [ :user | ( opts [ :preload ] || [ ] ) ]
98
+ Repo . preload ( jobs , preloads )
99
+ end
100
+
58
101
@ spec create_payment_session ( User . t ( ) | nil , JobPosting . t ( ) , Money . t ( ) ) ::
59
102
{ :ok , String . t ( ) } | { :error , atom ( ) }
60
103
def create_payment_session ( user , job_posting , amount ) do
0 commit comments