feat(jef-57): flag likely ghosted applications - #294
mankatcheung merged 1 commit into
Conversation
WalkthroughThe API now classifies applications as likely ghosted after 14 days of inactivity. GraphQL supports filtering and exposes the classification. The applications board adds route filtering, query propagation, empty-state text, and status badges. ChangesLikely ghosted applications
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
actor Applicant
participant ApplicationsPage
participant applicationsPage
participant GetApplicationsPageUseCase
participant DrizzleApplicationRepository
participant ApplicationMapper
Applicant->>ApplicationsPage: select “Likely ghosted”
ApplicationsPage->>applicationsPage: send likelyGhosted variable
applicationsPage->>GetApplicationsPageUseCase: request filtered page
GetApplicationsPageUseCase->>DrizzleApplicationRepository: query stale active applications
DrizzleApplicationRepository-->>GetApplicationsPageUseCase: return matching applications
GetApplicationsPageUseCase->>ApplicationMapper: map application results
ApplicationMapper-->>ApplicationsPage: return likelyGhosted fields
ApplicationsPage-->>Applicant: show filtered cards and badges
Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@apps/web/src/routes/_authenticated/applications/-components/ApplicationsPage.tsx`:
- Around line 154-160: Update the likelyGhosted Link’s search configuration in
ApplicationsPage so it uses the functional search updater, preserves all
existing query parameters such as status and starred, and only toggles the
likelyGhosted value based on the current state.
In `@apps/web/src/routes/_authenticated/applications/index.tsx`:
- Around line 33-41: Update APPLICATIONS_PAGE_QUERY’s applicationsPage items
selection to include the likelyGhosted field, matching the required
$likelyGhosted variable and ensuring each application result exposes its likely
ghosted state to list cards.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 78a14a87-5404-4eaf-88b7-785fe291d234
📒 Files selected for processing (14)
apps/api/src/__tests__/application/jobs/applicationStaleness.test.tsapps/api/src/http/schema/queries/applicationQueries.tsapps/api/src/http/schema/types/ApplicationType.tsapps/api/src/infrastructure/db/repositories/DrizzleApplicationRepository.tsapps/api/src/interface-adapters/mappers/ApplicationMapper.tsapps/api/src/interface-adapters/resolvers/ApplicationResolver.tsapps/api/src/use-cases/jobs/GetApplicationsPageUseCase.tsapps/api/src/use-cases/jobs/IGetApplicationsPageUseCase.tsapps/api/src/use-cases/jobs/applicationStaleness.tsapps/api/src/use-cases/ports/IApplicationRepository.tsapps/web/src/routes/_authenticated/applications/-board-page.tsxapps/web/src/routes/_authenticated/applications/-board-queries.tsapps/web/src/routes/_authenticated/applications/-components/ApplicationsPage.tsxapps/web/src/routes/_authenticated/applications/index.tsx
| <Link | ||
| to="/applications" | ||
| search={likelyGhosted ? {} : { likelyGhosted: true }} | ||
| className={`text-xs px-3 py-1.5 rounded-full border transition-colors ${likelyGhosted ? 'bg-amber-500 text-white border-amber-500' : 'bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-400 border-gray-200 dark:border-gray-700 hover:border-amber-400'}`} | ||
| > | ||
| Likely ghosted | ||
| </Link> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== dependency versions =="
if [ -f package.json ]; then jq -r '.dependencies["`@tanstack/react-router`"], .devDependencies["`@tanstack/react-router`"]' package.json; fi
if [ -f pnpm-lock.yaml ]; then rg -n "`@tanstack/react-router`:(.*)" pnpm-lock.yaml | head -20 || true; fi
if [ -f yarn.lock ]; then rg -n "`@tanstack/react-router`@|`@tanstack/react-router`:" yarn.lock | head -20 || true; fi
if [ -f package-lock.json ]; then jq -r '.packages["node_modules/@tanstack/react-router"].version // empty, .dependencies["`@tanstack/react-router`"].version // empty' package-lock.json 2>/dev/null || true; fi
echo
echo "== target file outline/usages =="
fd -a 'ApplicationsPage\.tsx$' . | sed 's#^\./##'
file="$(fd 'ApplicationsPage\.tsx$' apps/web/src/routes | head -1 || true)"
if [ -n "${file:-}" ]; then
wc -l "$file"
ast-grep outline "$file" --view compact || true
sed -n '1,220p' "$file"
fi
echo
echo "== likelyGhosted status starred search usages =="
rg -n "likelyGhosted|status|starred" apps/web/src/routes -g '*.tsx' -g '*.ts' || trueRepository: mankatcheung/job-finder
Length of output: 26720
🌐 Web query:
TanStack Router navigate search functional updater preserves search params search prop
💡 Result:
In TanStack Router, using a functional updater with the search property is the recommended way to modify search parameters while preserving existing ones [1][2]. When you provide a function to the search prop (in the Link component) or the search option (in navigate or useNavigate), the router passes the current search parameters as an argument to that function [1][3]. You can then return a new object containing your updates, merging it with the previous parameters [1][2]. Example usage: // Using navigate navigate({ search: (prev) => ({...prev, page: 1 }), }) // Using Link <Link search={(prev) => ({...prev, page: 1 })}> Next Page By using the spread operator ({...prev,... }), you ensure that any existing search parameters—including those inherited from parent routes—are maintained [2]. If you instead provide a plain object as the search value, it will typically replace or overwrite the existing search parameters [2]. For more complex scenarios, such as needing to remove specific parameters, you can destructure them within the functional updater: navigate({ search: (prev) => { const { unwantedParam,...rest } = prev; return rest; }, }) This functional approach is essential for maintaining application state that is stored in the URL, especially in deeply nested route structures where parent search parameters must be preserved during navigation [2].
Citations:
- 1: https://tanstack.com/router/latest/docs/how-to/navigate-with-search-params
- 2: https://tanstack.com/router/latest/docs/how-to/share-search-params-across-routes
- 3: https://tanstack.com/router/latest/docs/guide/search-params.md
Preserve existing URL filters when toggling likelyGhosted.
This search prop replaces the current search state. If status or starred is active, clicking the link removes those filters when it adds or removes likelyGhosted. Use the functional search updater and keep the previous parameters.
Proposed fix
- search={likelyGhosted ? {} : { likelyGhosted: true }}
+ search={(prev) => {
+ if (likelyGhosted) {
+ const next = { ...prev };
+ delete next.likelyGhosted;
+ return next;
+ }
+ return { ...prev, likelyGhosted: true };
+ }}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <Link | |
| to="/applications" | |
| search={likelyGhosted ? {} : { likelyGhosted: true }} | |
| className={`text-xs px-3 py-1.5 rounded-full border transition-colors ${likelyGhosted ? 'bg-amber-500 text-white border-amber-500' : 'bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-400 border-gray-200 dark:border-gray-700 hover:border-amber-400'}`} | |
| > | |
| Likely ghosted | |
| </Link> | |
| <Link | |
| to="/applications" | |
| search={(prev) => { | |
| if (likelyGhosted) { | |
| const next = { ...prev }; | |
| delete next.likelyGhosted; | |
| return next; | |
| } | |
| return { ...prev, likelyGhosted: true }; | |
| }} | |
| className={`text-xs px-3 py-1.5 rounded-full border transition-colors ${likelyGhosted ? 'bg-amber-500 text-white border-amber-500' : 'bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-400 border-gray-200 dark:border-gray-700 hover:border-amber-400'}`} | |
| > | |
| Likely ghosted | |
| </Link> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@apps/web/src/routes/_authenticated/applications/-components/ApplicationsPage.tsx`
around lines 154 - 160, Update the likelyGhosted Link’s search configuration in
ApplicationsPage so it uses the functional search updater, preserves all
existing query parameters such as status and starred, and only toggles the
likelyGhosted value based on the current state.
| $likelyGhosted: Boolean | ||
| ) { | ||
| applicationsPage( | ||
| status: $status | ||
| starred: $starred | ||
| search: $search | ||
| cursor: $cursor | ||
| limit: $limit | ||
| likelyGhosted: $likelyGhosted |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Select likelyGhosted in APPLICATIONS_PAGE_QUERY.
Line 76 declares likelyGhosted as required. The items selection does not request this field. GraphQL therefore omits it from list results, and list cards cannot display the likely ghosted state.
Proposed fix
items {
id
company
role
status
+ likelyGhosted
locationAlso applies to: 76-76
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/src/routes/_authenticated/applications/index.tsx` around lines 33 -
41, Update APPLICATIONS_PAGE_QUERY’s applicationsPage items selection to include
the likelyGhosted field, matching the required $likelyGhosted variable and
ensuring each application result exposes its likely ghosted state to list cards.
Summary
Add computed stale-application detection without introducing a new application status.
Rule
An application is marked likely ghosted when:
Changes
Verification
Summary by CodeRabbit