diff --git a/.claude/skills/check-dev-servers.md b/.claude/skills/check-dev-servers.md new file mode 100644 index 0000000..25c31be --- /dev/null +++ b/.claude/skills/check-dev-servers.md @@ -0,0 +1,43 @@ +# Check Dev Servers + +Check the tmux session for backend and frontend dev server status, read errors, and relaunch if needed. + +## Instructions + +1. **Find the tmux session** for the current worktree: + - Get the worktree directory name from `basename $PWD` or the known session name + - The session name matches the worktree directory name + - Window 1 = backend (Django runserver), Window 2 = frontend (npm run dev) + +2. **Capture output from both windows** in parallel: + ```bash + tmux capture-pane -t ':1' -p -S -80 + tmux capture-pane -t ':2' -p -S -80 + ``` + +3. **Analyze the output**: + - Look for Python tracebacks, Django errors, or "Error" messages in window 1 + - Look for build errors, compilation failures, or crash messages in window 2 + - Svelte a11y warnings are NOT errors - ignore them + - Report findings to the user + +4. **Relaunch if server is down**: + - For backend (window 1): Extract the port from the window name (e.g., `backend:8004` means port 8004) + ```bash + tmux send-keys -t ':1' 'workon tally && cd /Users/rasca/Dev//backend && python manage.py runserver ' Enter + ``` + - For frontend (window 2): Extract the port from the window name (e.g., `frontend:5004` means port 5004) + ```bash + tmux send-keys -t ':2' 'source ../backend/env/bin/activate && cd /Users/rasca/Dev//frontend && npm run dev -- --port ' Enter + ``` + +5. **Wait a few seconds then verify** the server started successfully: + ```bash + sleep 3 + tmux capture-pane -t ':' -p -S -20 + ``` + +## Common Issues +- Missing environment variables in `.env` -> check `.env.example` for defaults +- Port already in use -> check with `lsof -i :` +- Missing dependencies -> run `pip install -r requirements.txt` or `npm install` diff --git a/backend/contributions/views.py b/backend/contributions/views.py index 5193916..f328a0d 100644 --- a/backend/contributions/views.py +++ b/backend/contributions/views.py @@ -662,10 +662,16 @@ def create(self, request, *args, **kwargs): status=status.HTTP_403_FORBIDDEN ) if contribution_type.category.slug == 'validator' and not hasattr(request.user, 'validator'): - return Response( - {'error': 'You must complete the Validator Waitlist journey before submitting validator contributions.'}, - status=status.HTTP_403_FORBIDDEN - ) + # Allow users on the validator waitlist to submit validator contributions + has_waitlist = Contribution.objects.filter( + user=request.user, + contribution_type__slug='validator-waitlist' + ).exists() + if not has_waitlist: + return Response( + {'error': 'You must complete the Validator Waitlist journey before submitting validator contributions.'}, + status=status.HTTP_403_FORBIDDEN + ) except ContributionType.DoesNotExist: pass diff --git a/frontend/src/routes/SubmitContribution.svelte b/frontend/src/routes/SubmitContribution.svelte index a30e09f..f8a98c4 100644 --- a/frontend/src/routes/SubmitContribution.svelte +++ b/frontend/src/routes/SubmitContribution.svelte @@ -353,7 +353,7 @@ defaultContributionType={formData.contribution_type} onlySubmittable={true} stewardMode={false} - isValidator={!!$userStore.user?.validator} + isValidator={!!$userStore.user?.validator || !!$userStore.user?.has_validator_waitlist} isBuilder={!!$userStore.user?.builder} onSelectionChange={handleSelectionChange} />